From 5b63b3eb6f42f3d9f6a19b22c3f10f72927eeacc Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 10 Dec 2010 12:00:00 -0800 Subject: [PATCH 01/75] Use cv_timedwait_interruptible in arc The issue is that cv_timedwait() sleeps uninterruptibly to block signals and avoid waking up early. Under Linux this counts against the load average keeping it artificially high. This change allows the arc to sleep interruptibly which mean it may be woken up early due to a signal. Normally this means some extra care must be taken to handle a potential signal. But for the arcs usage of cv_timedwait() there is no harm in waking up before the timeout expires so no extra handling is required. --- include/sys/zfs_context.h | 1 + module/zfs/arc.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index c44990351..44e3dd1d3 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -310,6 +310,7 @@ extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); extern void cv_signal(kcondvar_t *cv); extern void cv_broadcast(kcondvar_t *cv); +#define cv_timedwait_interruptible(cv, mp, at) cv_timedwait(cv, mp, at); /* * kstat creation, installation and deletion diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 32d99bf39..808c8e8df 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -2149,7 +2149,7 @@ arc_reclaim_thread(void) /* block until needed, or one second, whichever is shorter */ CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait(&arc_reclaim_thr_cv, + (void) cv_timedwait_interruptible(&arc_reclaim_thr_cv, &arc_reclaim_thr_lock, (ddi_get_lbolt() + hz)); CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_thr_lock); } @@ -4435,8 +4435,8 @@ l2arc_feed_thread(void) while (l2arc_thread_exit == 0) { CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock, - next); + (void) cv_timedwait_interruptible(&l2arc_feed_thr_cv, + &l2arc_feed_thr_lock, next); CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock); next = ddi_get_lbolt() + hz; From 683fe41fc718fd43f57aa9ca76457fe34e62057c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 10 Dec 2010 12:54:30 -0800 Subject: [PATCH 02/75] Add missing mkdirp prototype For while now mkdirp has been built as part of libspl however the protoype was never added to libgen.h. This went unnoticed until enabling the mount support which uses mkdirp(). --- lib/libspl/include/libgen.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 lib/libspl/include/libgen.h diff --git a/lib/libspl/include/libgen.h b/lib/libspl/include/libgen.h new file mode 100644 index 000000000..29e5400d4 --- /dev/null +++ b/lib/libspl/include/libgen.h @@ -0,0 +1,34 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBSPL_LIBGEN_H +#define _LIBSPL_LIBGEN_H + +#include + +extern int mkdirp(const char *, mode_t); + +#endif /* _LIBSPL_LIBGEN_H */ From 149e873ab174ded1f632f2b2eb2267593517c7ca Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 14:05:42 -0800 Subject: [PATCH 03/75] Fix minor compiler warnings These compiler warnings were introduced when code which was previously #ifdef'ed out by HAVE_ZPL was re-added for use by the posix layer. All of the following changes should be obviously correct and will cause no semantic changes. --- cmd/zfs/zfs_main.c | 12 ++++----- cmd/zinject/zinject.c | 2 +- lib/libzfs/libzfs_mount.c | 2 +- module/zfs/zfs_acl.c | 38 ++++++++++++++-------------- module/zfs/zfs_dir.c | 6 ++--- module/zfs/zfs_vfsops.c | 18 +++++++------ module/zfs/zfs_vnops.c | 53 ++++++++++++++++++++------------------- module/zfs/zfs_znode.c | 2 +- 8 files changed, 68 insertions(+), 65 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 5f22e434e..e2c39a856 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3153,11 +3153,11 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol, shared_nfs = zfs_is_shared_nfs(zhp, NULL); shared_smb = zfs_is_shared_smb(zhp, NULL); - if (shared_nfs && shared_smb || - (shared_nfs && strcmp(shareopts, "on") == 0 && - strcmp(smbshareopts, "off") == 0) || - (shared_smb && strcmp(smbshareopts, "on") == 0 && - strcmp(shareopts, "off") == 0)) { + if ((shared_nfs && shared_smb) || + ((shared_nfs && strcmp(shareopts, "on") == 0) && + (strcmp(smbshareopts, "off") == 0)) || + ((shared_smb && strcmp(smbshareopts, "on") == 0) && + (strcmp(shareopts, "off") == 0))) { if (!explicit) return (0); @@ -3622,7 +3622,7 @@ unshare_unmount(int op, int argc, char **argv) */ struct mnttab entry; uu_avl_pool_t *pool; - uu_avl_t *tree; + uu_avl_t *tree = NULL; unshare_unmount_node_t *node; uu_avl_index_t idx; uu_avl_walk_t *walk; diff --git a/cmd/zinject/zinject.c b/cmd/zinject/zinject.c index 3ad90e329..e76e626fa 100644 --- a/cmd/zinject/zinject.c +++ b/cmd/zinject/zinject.c @@ -566,7 +566,7 @@ main(int argc, char **argv) zinject_record_t record = { 0 }; char pool[MAXNAMELEN]; char dataset[MAXNAMELEN]; - zfs_handle_t *zhp; + zfs_handle_t *zhp = NULL; int nowrites = 0; int dur_txg = 0; int dur_secs = 0; diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 4b9038de8..88bd0714e 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -467,7 +467,7 @@ zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto) if (!zfs_is_mounted(zhp, &mountpoint)) return (SHARED_NOT_SHARED); - if (rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) { + if ((rc = is_shared(zhp->zfs_hdl, mountpoint, proto))) { if (where != NULL) *where = mountpoint; else diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index f1ba9af57..3efd4f88e 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -494,7 +494,7 @@ zfs_acl_release_nodes(zfs_acl_t *aclp) { zfs_acl_node_t *aclnode; - while (aclnode = list_head(&aclp->z_acl)) { + while ((aclnode = list_head(&aclp->z_acl))) { list_remove(&aclp->z_acl, aclnode); zfs_acl_node_free(aclnode); } @@ -732,8 +732,8 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, size_t ace_size; uint16_t entry_type; - while (zacep = zfs_acl_next_ace(aclp, zacep, - &who, &access_mask, &iflags, &type)) { + while ((zacep = zfs_acl_next_ace(aclp, zacep, + &who, &access_mask, &iflags, &type))) { switch (type) { case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: @@ -823,8 +823,8 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr) oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count, KM_SLEEP); i = 0; - while (cookie = zfs_acl_next_ace(aclp, cookie, &who, - &access_mask, &iflags, &type)) { + while ((cookie = zfs_acl_next_ace(aclp, cookie, &who, + &access_mask, &iflags, &type))) { oldaclp[i].z_flags = iflags; oldaclp[i].z_type = type; oldaclp[i].z_fuid = who; @@ -904,8 +904,8 @@ zfs_mode_compute(uint64_t fmode, zfs_acl_t *aclp, mode = (fmode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)); - while (acep = zfs_acl_next_ace(aclp, acep, &who, - &access_mask, &iflags, &type)) { + while ((acep = zfs_acl_next_ace(aclp, acep, &who, + &access_mask, &iflags, &type))) { if (!zfs_acl_valid_ace_type(type, iflags)) continue; @@ -1441,8 +1441,8 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp) new_bytes += abstract_size; } - while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, - &iflags, &type)) { + while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, + &iflags, &type))) { uint16_t inherit_flags; entry_type = (iflags & ACE_TYPE_FLAGS); @@ -1584,8 +1584,8 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, aclp = zfs_acl_alloc(paclp->z_version); if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD || vtype == VLNK) return (aclp); - while (pacep = zfs_acl_next_ace(paclp, pacep, &who, - &access_mask, &iflags, &type)) { + while ((pacep = zfs_acl_next_ace(paclp, pacep, &who, + &access_mask, &iflags, &type))) { /* * don't inherit bogus ACEs @@ -1837,7 +1837,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (mask == 0) return (ENOSYS); - if (error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)) + if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr))) return (error); mutex_enter(&zp->z_acl_lock); @@ -1857,8 +1857,8 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) uint32_t access_mask; uint16_t type, iflags; - while (zacep = zfs_acl_next_ace(aclp, zacep, - &who, &access_mask, &iflags, &type)) { + while ((zacep = zfs_acl_next_ace(aclp, zacep, + &who, &access_mask, &iflags, &type))) { switch (type) { case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: @@ -1996,7 +1996,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (zp->z_pflags & ZFS_IMMUTABLE) return (EPERM); - if (error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)) + if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))) return (error); error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp, @@ -2173,8 +2173,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, ASSERT(zp->z_acl_cached); - while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, - &iflags, &type)) { + while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, + &iflags, &type))) { uint32_t mask_matched; if (!zfs_acl_valid_ace_type(type, iflags)) @@ -2730,14 +2730,14 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, * If that succeeds then check for add_file/add_subdir permissions */ - if (error = zfs_zaccess_delete(sdzp, szp, cr)) + if ((error = zfs_zaccess_delete(sdzp, szp, cr))) return (error); /* * If we have a tzp, see if we can delete it? */ if (tzp) { - if (error = zfs_zaccess_delete(tdzp, tzp, cr)) + if ((error = zfs_zaccess_delete(tdzp, tzp, cr))) return (error); } diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c index f0084cd4e..a1f3df1a0 100644 --- a/module/zfs/zfs_dir.c +++ b/module/zfs/zfs_dir.c @@ -153,9 +153,9 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, /* * Verify that we are not trying to lock '.', '..', or '.zfs' */ - if (name[0] == '.' && - (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) || - zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) + if ((name[0] == '.' && + (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) || + (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0)) return (EEXIST); /* diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 77bef009b..30bbcccb4 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -485,8 +485,8 @@ zfs_register_callbacks(vfs_t *vfsp) char osname[MAXNAMELEN]; dmu_objset_name(os, osname); - if (error = dsl_prop_get_integer(osname, "nbmand", &nbmand, - NULL)) { + if ((error = dsl_prop_get_integer(osname, "nbmand", &nbmand, + NULL))) { return (error); } } @@ -642,6 +642,8 @@ zfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type) return (zfsvfs->z_userquota_obj); case ZFS_PROP_GROUPQUOTA: return (zfsvfs->z_groupquota_obj); + default: + return (ENOTSUP); } return (0); } @@ -873,7 +875,7 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) goto out; } else if (zfsvfs->z_version > zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) { - (void) printf("Can't mount a version %lld file system " + (void) printk("Can't mount a version %lld file system " "on a version %lld pool\n. Pool must be upgraded to mount " "this file system.", (u_longlong_t)zfsvfs->z_version, (u_longlong_t)spa_version(dmu_objset_spa(os))); @@ -1126,8 +1128,8 @@ zfs_domount(vfs_t *vfsp, char *osname) } ASSERT(vfs_devismounted(mount_dev) == 0); - if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize, - NULL)) + if ((error = dsl_prop_get_integer(osname, "recordsize", + &recordsize, NULL))) goto out; vfsp->vfs_dev = mount_dev; @@ -1169,7 +1171,7 @@ zfs_domount(vfs_t *vfsp, char *osname) atime_changed_cb(zfsvfs, B_FALSE); readonly_changed_cb(zfsvfs, B_TRUE); - if (error = dsl_prop_get_integer(osname, "xattr", &pval, NULL)) + if ((error = dsl_prop_get_integer(osname,"xattr",&pval,NULL))) goto out; xattr_changed_cb(zfsvfs, pval); zfsvfs->z_issnap = B_TRUE; @@ -1565,7 +1567,7 @@ zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) /* * Get the objset name (the "special" mount argument). */ - if (error = pn_get(uap->spec, fromspace, &spn)) + if ((error = pn_get(uap->spec, fromspace, &spn))) return (error); osname = spn.pn_path; @@ -1968,7 +1970,7 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) gen_mask = -1ULL >> (64 - 8 * i); dprintf("getting %llu [%u mask %llx]\n", object, fid_gen, gen_mask); - if (err = zfs_zget(zfsvfs, object, &zp)) { + if ((err = zfs_zget(zfsvfs, object, &zp))) { ZFS_EXIT(zfsvfs); return (err); } diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 5899c7f7d..44bae8e34 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -450,7 +450,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) zfsvfs_t *zfsvfs = zp->z_zfsvfs; objset_t *os; ssize_t n, nbytes; - int error; + int error = 0; rl_t *rl; xuio_t *xuio = NULL; @@ -763,8 +763,8 @@ again: max_blksz); ASSERT(abuf != NULL); ASSERT(arc_buf_size(abuf) == max_blksz); - if (error = uiocopy(abuf->b_data, max_blksz, - UIO_WRITE, uio, &cbytes)) { + if ((error = uiocopy(abuf->b_data, max_blksz, + UIO_WRITE, uio, &cbytes))) { dmu_return_arcbuf(abuf); break; } @@ -1223,7 +1223,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, return (EINVAL); } - if (error = zfs_get_xattrdir(VTOZ(dvp), vpp, cr, flags)) { + if ((error = zfs_get_xattrdir(VTOZ(dvp), vpp, cr, flags))) { ZFS_EXIT(zfsvfs); return (error); } @@ -1232,8 +1232,8 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, * Do we have permission to get into attribute directory? */ - if (error = zfs_zaccess(VTOZ(*vpp), ACE_EXECUTE, 0, - B_FALSE, cr)) { + if ((error = zfs_zaccess(VTOZ(*vpp), ACE_EXECUTE, 0, + B_FALSE, cr))) { VN_RELE(*vpp); *vpp = NULL; } @@ -1251,7 +1251,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, * Check accessibility of directory. */ - if (error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr)) { + if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) { ZFS_EXIT(zfsvfs); return (error); } @@ -1310,7 +1310,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl, int error; ksid_t *ksid; uid_t uid; - gid_t gid = crgetgid(cr); + gid_t gid; zfs_acl_ids_t acl_ids; boolean_t fuid_dirtied; boolean_t have_acl = B_FALSE; @@ -1320,6 +1320,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl, * make sure file system is at proper version */ + gid = crgetgid(cr); ksid = crgetsid(cr, KSID_OWNER); if (ksid) uid = ksid_getid(ksid); @@ -1389,7 +1390,7 @@ top: * Create a new file object and update the directory * to reference it. */ - if (error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr)) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { if (have_acl) zfs_acl_ids_free(&acl_ids); goto out; @@ -1587,8 +1588,8 @@ top: /* * Attempt to lock directory; fail if entry doesn't exist. */ - if (error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, - NULL, realnmp)) { + if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, + NULL, realnmp))) { if (realnmp) pn_free(realnmp); ZFS_EXIT(zfsvfs); @@ -1597,7 +1598,7 @@ top: vp = ZTOV(zp); - if (error = zfs_zaccess_delete(dzp, zp, cr)) { + if ((error = zfs_zaccess_delete(dzp, zp, cr))) { goto out; } @@ -1617,7 +1618,7 @@ top: dnlc_remove(dvp, name); mutex_enter(&vp->v_lock); - may_delete_now = vp->v_count == 1 && !vn_has_cached_data(vp); + may_delete_now = ((vp->v_count == 1) && (!vn_has_cached_data(vp))); mutex_exit(&vp->v_lock); /* @@ -1856,14 +1857,14 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, top: *vpp = NULL; - if (error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, - NULL, NULL)) { + if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, + NULL, NULL))) { zfs_acl_ids_free(&acl_ids); ZFS_EXIT(zfsvfs); return (error); } - if (error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr)) { + if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); ZFS_EXIT(zfsvfs); @@ -1987,15 +1988,15 @@ top: /* * Attempt to lock directory; fail if entry doesn't exist. */ - if (error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, - NULL, NULL)) { + if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, + NULL, NULL))) { ZFS_EXIT(zfsvfs); return (error); } vp = ZTOV(zp); - if (error = zfs_zaccess_delete(dzp, zp, cr)) { + if ((error = zfs_zaccess_delete(dzp, zp, cr))) { goto out; } @@ -2442,8 +2443,8 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, */ if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) && (vap->va_uid != crgetuid(cr))) { - if (error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0, - skipaclchk, cr)) { + if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0, + skipaclchk, cr))) { ZFS_EXIT(zfsvfs); return (error); } @@ -3520,7 +3521,7 @@ top: * done in a single check. */ - if (error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)) + if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr))) goto out; if (ZTOV(szp)->v_type == VDIR) { @@ -3528,7 +3529,7 @@ top: * Check to make sure rename is valid. * Can't do a move like this: /usr/a/b to /usr/a/b/c/d */ - if (error = zfs_rename_lock(szp, tdzp, sdzp, &zl)) + if ((error = zfs_rename_lock(szp, tdzp, sdzp, &zl))) goto out; } @@ -3746,7 +3747,7 @@ top: return (error); } - if (error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr)) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); ZFS_EXIT(zfsvfs); @@ -3969,7 +3970,7 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, return (EPERM); } - if (error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr)) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { ZFS_EXIT(zfsvfs); return (error); } @@ -4727,7 +4728,7 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, return (EINVAL); } - if (error = convoff(vp, bfp, 0, offset)) { + if ((error = convoff(vp, bfp, 0, offset))) { ZFS_EXIT(zfsvfs); return (error); } diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 4f6185fb5..93f2f026e 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -1000,7 +1000,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, if (obj_type == DMU_OT_ZNODE || acl_ids->z_aclp->z_version < ZFS_ACL_VERSION_FUID) { err = zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx); - ASSERT3P(err, ==, 0); + ASSERT3S(err, ==, 0); } ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); } From 95c73795b001267d6b683b71e8abe51de4b0c938 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 7 Jan 2011 12:24:03 -0800 Subject: [PATCH 04/75] Fix ZVOL rename minor devices During a rename we need to be careful to destroy and create a new minor for the ZVOL _only_ if the rename succeeded. The previous code would both destroy you minor device unconditionally, it would also fail to create the new minor device on success. --- module/zfs/zfs_ioctl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 45e118e53..6e8422bb0 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -3307,6 +3307,7 @@ static int zfs_ioc_rename(zfs_cmd_t *zc) { boolean_t recursive = zc->zc_cookie & 1; + int err; zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || @@ -3320,13 +3321,18 @@ zfs_ioc_rename(zfs_cmd_t *zc) */ if (!recursive && strchr(zc->zc_name, '@') != NULL && zc->zc_objset_type == DMU_OST_ZFS) { - int err = zfs_unmount_snap(zc->zc_name, NULL); + err = zfs_unmount_snap(zc->zc_name, NULL); if (err) return (err); } - if (zc->zc_objset_type == DMU_OST_ZVOL) + + err = dmu_objset_rename(zc->zc_name, zc->zc_value, recursive); + if ((err == 0) && (zc->zc_objset_type == DMU_OST_ZVOL)) { (void) zvol_remove_minor(zc->zc_name); - return (dmu_objset_rename(zc->zc_name, zc->zc_value, recursive)); + (void) zvol_create_minor(zc->zc_value); + } + + return (err); } static int From b3259b6a2ba29595dc5f2df0f6def8c7fc6bcb98 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 14:26:08 -0800 Subject: [PATCH 05/75] Autoconf selinux support If libselinux is detected on your system at configure time link against it. This allows us to use a library call to detect if selinux is enabled and if it is to pass the mount option: "context=\"system_u:object_r:file_t:s0" For now this is required because none of the existing selinux policies are aware of the zfs filesystem type. Because of this they do not properly enable xattr based labeling even though zfs supports all of the required hooks. Until distro's add zfs as a known xattr friendly fs type we must use mntpoint labeling. Alternately, end users could modify their existing selinux policy with a little guidance. --- Makefile.in | 2 + cmd/Makefile.in | 2 + cmd/zdb/Makefile.in | 2 + cmd/zfs/Makefile.in | 2 + cmd/zinject/Makefile.in | 2 + cmd/zpios/Makefile.in | 2 + cmd/zpool/Makefile.in | 2 + cmd/zpool_id/Makefile.in | 2 + cmd/zpool_layout/Makefile.in | 2 + cmd/ztest/Makefile.in | 2 + config/user-selinux.m4 | 36 ++ config/user.m4 | 1 + configure | 555 +++++++++++++++++++- etc/Makefile.in | 2 + include/Makefile.in | 2 + include/sys/Makefile.in | 2 + include/sys/fm/Makefile.in | 2 + include/sys/fm/fs/Makefile.in | 2 + include/sys/fs/Makefile.in | 2 + lib/Makefile.in | 2 + lib/libavl/Makefile.in | 2 + lib/libefi/Makefile.in | 2 + lib/libnvpair/Makefile.in | 2 + lib/libspl/Makefile.in | 2 + lib/libspl/asm-generic/Makefile.in | 2 + lib/libspl/asm-i386/Makefile.in | 2 + lib/libspl/asm-x86_64/Makefile.in | 2 + lib/libspl/include/Makefile.in | 2 + lib/libspl/include/ia32/Makefile.in | 2 + lib/libspl/include/ia32/sys/Makefile.in | 2 + lib/libspl/include/rpc/Makefile.in | 2 + lib/libspl/include/sys/Makefile.in | 2 + lib/libspl/include/sys/dktp/Makefile.in | 2 + lib/libspl/include/sys/sysevent/Makefile.in | 2 + lib/libspl/include/util/Makefile.in | 2 + lib/libunicode/Makefile.in | 2 + lib/libuutil/Makefile.in | 2 + lib/libzfs/Makefile.am | 2 +- lib/libzfs/Makefile.in | 4 +- lib/libzfs/libzfs_mount.c | 9 + lib/libzpool/Makefile.in | 2 + man/Makefile.in | 2 + man/man8/Makefile.in | 2 + scripts/Makefile.in | 2 + scripts/zpios-profile/Makefile.in | 2 + scripts/zpios-test/Makefile.in | 2 + scripts/zpool-config/Makefile.in | 2 + scripts/zpool-layout/Makefile.in | 2 + zfs_config.h.in | 3 + 49 files changed, 678 insertions(+), 16 deletions(-) create mode 100644 config/user-selinux.m4 diff --git a/Makefile.in b/Makefile.in index 250248249..09708bf4a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,6 +80,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -210,6 +211,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index f8f5a7697..bed295156 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -178,6 +179,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index 88152b846..b84eb2c0f 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -180,6 +181,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index dd44b2684..6bd1f3fbd 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -180,6 +181,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index ddf61bce9..c2598673e 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -180,6 +181,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index 911f9c338..c30a3e04d 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -170,6 +171,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index 258de649b..b628756bd 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -181,6 +182,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index 6d2fd50e4..932bc25f3 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index ea8947cbc..9b1b5ebae 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index c102d0292..3b4e7c45e 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -68,6 +68,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -180,6 +181,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/config/user-selinux.m4 b/config/user-selinux.m4 new file mode 100644 index 000000000..84df6ce7b --- /dev/null +++ b/config/user-selinux.m4 @@ -0,0 +1,36 @@ +dnl # +dnl # Check to see if the selinux libraries are available. If they +dnl # are then they will be consulted during mount to determine if +dnl # selinux is enabled or disabled. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBSELINUX], [ + AC_ARG_WITH([selinux], + [AS_HELP_STRING([--with-selinux], + [support selinux @<:@default=check@:>@])], + [], + [with_selinux=check]) + + LIBSELINUX= + AS_IF([test "x$with_selinux" != xno], [ + AC_CHECK_HEADER([selinux/selinux.h], [ + AC_CHECK_LIB([selinux], [is_selinux_enabled], [ + AC_SUBST([LIBSELINUX], ["-lselinux"]) + AC_DEFINE([HAVE_LIBSELINUX], 1, + [Define if you have selinux]) + ], [ + AS_IF([test "x$with_selinux" != xcheck], + [AC_MSG_FAILURE( + [--with-selinux given but unavailable]) + ]) + ]) + ], [ + AS_IF([test "x$with_selinux" != xcheck], + [AC_MSG_FAILURE( + [--with-selinux given but unavailable]) + ]) + ]) + ], [ + AC_MSG_CHECKING([for selinux support]) + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/user.m4 b/config/user.m4 index bc68808f8..6f0276937 100644 --- a/config/user.m4 +++ b/config/user.m4 @@ -8,6 +8,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_ZLIB ZFS_AC_CONFIG_USER_LIBUUID ZFS_AC_CONFIG_USER_LIBBLKID + ZFS_AC_CONFIG_USER_LIBSELINUX ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN ZFS_AC_CONFIG_USER_STACK_GUARD ]) diff --git a/configure b/configure index 8c4ce636c..48bf4cba1 100755 --- a/configure +++ b/configure @@ -794,6 +794,7 @@ CONFIG_KERNEL_TRUE CONFIG_USER_FALSE CONFIG_USER_TRUE FRAME_LARGER_THAN +LIBSELINUX LIBBLKID LIBUUID ZLIB @@ -972,6 +973,7 @@ with_linux_obj with_spl with_spl_obj with_blkid +with_selinux enable_debug ' ac_precious_vars='build_alias @@ -1639,6 +1641,7 @@ Optional Packages: --with-spl=PATH Path to spl source --with-spl-obj=PATH Path to spl build objects --with-blkid support blkid caching [default=check] + --with-selinux support selinux [default=check] Some influential environment variables: CC C compiler command @@ -4817,13 +4820,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:4820: $ac_compile\"" >&5) + (eval echo "\"\$as_me:4823: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:4823: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:4826: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:4826: output\"" >&5) + (eval echo "\"\$as_me:4829: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6029,7 +6032,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6032 "configure"' > conftest.$ac_ext + echo '#line 6035 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7882,11 +7885,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7885: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7888: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7889: \$? = $ac_status" >&5 + echo "$as_me:7892: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8221,11 +8224,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8224: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8227: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8228: \$? = $ac_status" >&5 + echo "$as_me:8231: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8326,11 +8329,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8329: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8332: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8333: \$? = $ac_status" >&5 + echo "$as_me:8336: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8381,11 +8384,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8384: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8387: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8388: \$? = $ac_status" >&5 + echo "$as_me:8391: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11184,7 +11187,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11187 "configure" +#line 11190 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11280,7 +11283,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11283 "configure" +#line 11286 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14979,6 +14982,268 @@ fi + +# Check whether --with-selinux was given. +if test "${with_selinux+set}" = set; then + withval=$with_selinux; +else + with_selinux=check +fi + + + LIBSELINUX= + if test "x$with_selinux" != xno; then + + if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 +$as_echo_n "checking for selinux/selinux.h... " >&6; } +if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 +$as_echo "$ac_cv_header_selinux_selinux_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking selinux/selinux.h usability" >&5 +$as_echo_n "checking selinux/selinux.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking selinux/selinux.h presence" >&5 +$as_echo_n "checking selinux/selinux.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 +$as_echo_n "checking for selinux/selinux.h... " >&6; } +if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_selinux_selinux_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 +$as_echo "$ac_cv_header_selinux_selinux_h" >&6; } + +fi +if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then + + { $as_echo "$as_me:$LINENO: checking for is_selinux_enabled in -lselinux" >&5 +$as_echo_n "checking for is_selinux_enabled in -lselinux... " >&6; } +if test "${ac_cv_lib_selinux_is_selinux_enabled+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char is_selinux_enabled (); +int +main () +{ +return is_selinux_enabled (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_selinux_is_selinux_enabled=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_selinux_is_selinux_enabled=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5 +$as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; } +if test "x$ac_cv_lib_selinux_is_selinux_enabled" = x""yes; then + + LIBSELINUX="-lselinux" + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBSELINUX 1 +_ACEOF + + +else + + if test "x$with_selinux" != xcheck; then + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: --with-selinux given but unavailable +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: --with-selinux given but unavailable +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +fi + + +fi + + +else + + if test "x$with_selinux" != xcheck; then + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: --with-selinux given but unavailable +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: --with-selinux given but unavailable +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +fi + + +fi + + + +else + + { $as_echo "$as_me:$LINENO: checking for selinux support" >&5 +$as_echo_n "checking for selinux support... " >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + +fi + + + { $as_echo "$as_me:$LINENO: checking for -Wframe-larger-than= support" >&5 $as_echo_n "checking for -Wframe-larger-than= support... " >&6; } @@ -18314,6 +18579,268 @@ fi + +# Check whether --with-selinux was given. +if test "${with_selinux+set}" = set; then + withval=$with_selinux; +else + with_selinux=check +fi + + + LIBSELINUX= + if test "x$with_selinux" != xno; then + + if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 +$as_echo_n "checking for selinux/selinux.h... " >&6; } +if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 +$as_echo "$ac_cv_header_selinux_selinux_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking selinux/selinux.h usability" >&5 +$as_echo_n "checking selinux/selinux.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking selinux/selinux.h presence" >&5 +$as_echo_n "checking selinux/selinux.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 +$as_echo_n "checking for selinux/selinux.h... " >&6; } +if test "${ac_cv_header_selinux_selinux_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_selinux_selinux_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 +$as_echo "$ac_cv_header_selinux_selinux_h" >&6; } + +fi +if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then + + { $as_echo "$as_me:$LINENO: checking for is_selinux_enabled in -lselinux" >&5 +$as_echo_n "checking for is_selinux_enabled in -lselinux... " >&6; } +if test "${ac_cv_lib_selinux_is_selinux_enabled+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char is_selinux_enabled (); +int +main () +{ +return is_selinux_enabled (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_selinux_is_selinux_enabled=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_selinux_is_selinux_enabled=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5 +$as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; } +if test "x$ac_cv_lib_selinux_is_selinux_enabled" = x""yes; then + + LIBSELINUX="-lselinux" + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBSELINUX 1 +_ACEOF + + +else + + if test "x$with_selinux" != xcheck; then + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: --with-selinux given but unavailable +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: --with-selinux given but unavailable +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +fi + + +fi + + +else + + if test "x$with_selinux" != xcheck; then + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: --with-selinux given but unavailable +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: --with-selinux given but unavailable +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +fi + + +fi + + + +else + + { $as_echo "$as_me:$LINENO: checking for selinux support" >&5 +$as_echo_n "checking for selinux support... " >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + +fi + + + { $as_echo "$as_me:$LINENO: checking for -Wframe-larger-than= support" >&5 $as_echo_n "checking for -Wframe-larger-than= support... " >&6; } diff --git a/etc/Makefile.in b/etc/Makefile.in index 5eb555171..eb8ad9570 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/include/Makefile.in b/include/Makefile.in index 6821a67fe..7a1f40ab5 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -222,6 +223,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 8964aae41..d3985cc8e 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -343,6 +344,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index 5e1f4b883..b27565995 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -207,6 +208,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index ed828ebdd..e8d289abe 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -167,6 +168,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index 3103ffa67..d1ee3b2d8 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -167,6 +168,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/Makefile.in b/lib/Makefile.in index 9749b774a..18ff05229 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -178,6 +179,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 930f8e580..500846a77 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -190,6 +191,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 294cac074..1f4409066 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -190,6 +191,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index 8f689d4d8..e1027d51c 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -191,6 +192,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 6bf147834..385a567c6 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -241,6 +242,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 8b87c314b..162c386ca 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -139,6 +140,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index fe9d9cb4f..9a26bb4d4 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -143,6 +144,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index 750690300..a00f235b7 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -143,6 +144,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index 1a0a7f8b1..360560052 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -203,6 +204,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index 4b97ee1b4..a9f80cde8 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -178,6 +179,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index 1b2fb35ee..fb0fe3f8c 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -165,6 +166,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index f5385d9d1..1fd162a47 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -165,6 +166,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index 20fdfca14..0746ded39 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -203,6 +204,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index 713aa88b6..499081af2 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -165,6 +166,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 858e38877..0a9c6d186 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -165,6 +166,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index 1cdbb5740..27aa363f3 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -165,6 +166,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index 1f431dad3..5daee2b73 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -190,6 +191,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index e600ba49f..1a28249ae 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -192,6 +193,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/lib/libzfs/Makefile.am b/lib/libzfs/Makefile.am index 70210c35b..de5212234 100644 --- a/lib/libzfs/Makefile.am +++ b/lib/libzfs/Makefile.am @@ -6,7 +6,7 @@ DEFAULT_INCLUDES += \ lib_LTLIBRARIES = libzfs.la -libzfs_la_LDFLAGS = -lm +libzfs_la_LDFLAGS = -lm $(LIBSELINUX) libzfs_la_LIBADD = \ $(top_builddir)/lib/libefi/libefi.la \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index 741f39da4..c8b500466 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -197,6 +198,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ @@ -314,7 +316,7 @@ AM_CFLAGS = -Wall -Wstrict-prototypes -fno-strict-aliasing \ -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64 \ -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\" lib_LTLIBRARIES = libzfs.la -libzfs_la_LDFLAGS = -lm +libzfs_la_LDFLAGS = -lm $(LIBSELINUX) libzfs_la_LIBADD = \ $(top_builddir)/lib/libefi/libefi.la \ $(top_builddir)/lib/libuutil/libuutil.la diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 88bd0714e..9950bf967 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -72,6 +72,9 @@ #include #include #include +#ifdef HAVE_LIBSELINUX +#include +#endif /* HAVE_LIBSELINUX */ #include @@ -277,6 +280,12 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) flags |= MS_RDONLY; +#ifdef HAVE_LIBSELINUX + if (is_selinux_enabled()) + (void) strlcat(mntopts, ",context=\"system_u:" + "object_r:file_t:s0\"", sizeof (mntopts)); +#endif /* HAVE_LIBSELINUX */ + if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 99ad7199c..421e55cc2 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -67,6 +67,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -211,6 +212,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/man/Makefile.in b/man/Makefile.in index c18b275c0..47a16fe64 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -178,6 +179,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index 8cace2c04..0a96d97bd 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 3e68eda65..076fc6c28 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -203,6 +204,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index 1aa13065f..fe89e1d00 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index dcd0fcacc..09f0503c7 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index 56a563031..71ef3c5f2 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index baa20881a..d270230fe 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ $(top_srcdir)/config/zfs-build.m4 \ $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac @@ -163,6 +164,7 @@ LDFLAGS = @LDFLAGS@ LIBBLKID = @LIBBLKID@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIBUUID = @LIBUUID@ LINUX = @LINUX@ diff --git a/zfs_config.h.in b/zfs_config.h.in index 6e0e62390..e1532f635 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -84,6 +84,9 @@ /* Define if you have libblkid */ #undef HAVE_LIBBLKID +/* Define if you have selinux */ +#undef HAVE_LIBSELINUX + /* Define to 1 if 'libshare' library available */ #undef HAVE_LIBSHARE From 3b8cfee8af1d966eea75389e2a2e53a5a8dca600 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 8 Dec 2010 16:40:11 -0800 Subject: [PATCH 06/75] Enable mount.zfs helper While not strictly required to mount a zfs filesystem using a mount helper has certain advantages. First, we need it if we want to honor the mount behavior as found on Solaris. As part of the mount we need to validate that the dataset has the legacy mount property set if we are using 'mount' instead of 'zfs mount'. Secondly, by using a mount helper we can automatically load the zpl kernel module. This way you can just issue a 'mount' or 'zfs mount' and it will just work. Finally, it gives us common hook in user space to add any zfs specific mount options we might want. At the moment we don't have any but now the infrastructure is at least in place. --- cmd/zfs/zfs_main.c | 222 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 189 insertions(+), 33 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index e2c39a856..2aa3e2ef1 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3864,45 +3864,208 @@ zfs_do_python(int argc, char **argv) return (-1); } +typedef struct option_map { + const char *name; + int mask; +} option_map_t; + +static const option_map_t option_map[] = { + /* Canonicalized filesystem independent options from mount(8) */ + { MNTOPT_NOAUTO, MS_COMMENT }, + { MNTOPT_DEFAULTS, MS_COMMENT }, + { MNTOPT_NODEVICES, MS_NODEV }, + { MNTOPT_DIRSYNC, MS_DIRSYNC }, + { MNTOPT_NOEXEC, MS_NOEXEC }, + { MNTOPT_GROUP, MS_GROUP }, + { MNTOPT_NETDEV, MS_COMMENT }, + { MNTOPT_NOFAIL, MS_COMMENT }, + { MNTOPT_NOSUID, MS_NOSUID }, + { MNTOPT_OWNER, MS_OWNER }, + { MNTOPT_REMOUNT, MS_REMOUNT }, + { MNTOPT_RO, MS_RDONLY }, + { MNTOPT_SYNC, MS_SYNCHRONOUS }, + { MNTOPT_USER, MS_USERS }, + { MNTOPT_USERS, MS_USERS }, +#ifdef MS_NOATIME + { MNTOPT_NOATIME, MS_NOATIME }, +#endif +#ifdef MS_NODIRATIME + { MNTOPT_NODIRATIME, MS_NODIRATIME }, +#endif +#ifdef MS_RELATIME + { MNTOPT_RELATIME, MS_RELATIME }, +#endif +#ifdef MS_STRICTATIME + { MNTOPT_DFRATIME, MS_STRICTATIME }, +#endif +#ifdef HAVE_SELINUX + { MNTOPT_CONTEXT, MS_COMMENT }, + { MNTOPT_FSCONTEXT, MS_COMMENT }, + { MNTOPT_DEFCONTEXT, MS_COMMENT }, + { MNTOPT_ROOTCONTEXT, MS_COMMENT }, +#endif +#ifdef MS_I_VERSION + { MNTOPT_IVERSION, MS_I_VERSION }, +#endif +#ifdef MS_MANDLOCK + { MNTOPT_NBMAND, MS_MANDLOCK }, +#endif + /* Valid options not found in mount(8) */ + { MNTOPT_BIND, MS_BIND }, + { MNTOPT_RBIND, MS_BIND|MS_REC }, + { MNTOPT_COMMENT, MS_COMMENT }, + { MNTOPT_BOOTWAIT, MS_COMMENT }, + { MNTOPT_NOBOOTWAIT, MS_COMMENT }, + { MNTOPT_OPTIONAL, MS_COMMENT }, + { MNTOPT_SHOWTHROUGH, MS_COMMENT }, +#ifdef MS_NOSUB + { MNTOPT_NOSUB, MS_NOSUB }, +#endif +#ifdef MS_SILENT + { MNTOPT_QUIET, MS_SILENT }, +#endif + /* Custom zfs options */ + { MNTOPT_NOXATTR, MS_COMMENT }, + { NULL, 0 } }; + /* - * Called when invoked as /etc/fs/zfs/mount. Do the mount if the mountpoint is - * 'legacy'. Otherwise, complain that use should be using 'zfs mount'. + * Break the mount option in to a name/value pair. The name is + * validated against the option map and mount flags set accordingly. + */ +static int +parse_option(char *mntopt, unsigned long *mntflags, int sloppy) +{ + const option_map_t *opt; + char *ptr, *name, *value = NULL; + int rc; + + name = strdup(mntopt); + if (name == NULL) + return (ENOMEM); + + for (ptr = name; ptr && *ptr; ptr++) { + if (*ptr == '=') { + *ptr = '\0'; + value = ptr+1; + break; + } + } + + for (opt = option_map; opt->name != NULL; opt++) { + if (strncmp(name, opt->name, strlen(name)) == 0) { + *mntflags |= opt->mask; + + /* MS_USERS implies default user options */ + if (opt->mask & (MS_USERS)) + *mntflags |= (MS_NOEXEC|MS_NOSUID|MS_NODEV); + + /* MS_OWNER|MS_GROUP imply default owner options */ + if (opt->mask & (MS_OWNER | MS_GROUP)) + *mntflags |= (MS_NOSUID|MS_NODEV); + + rc = 0; + goto out; + } + } + + if (!sloppy) + rc = ENOENT; +out: + /* If required further process on the value may be done here */ + free(name); + return (rc); +} + +/* + * Translate the mount option string in to MS_* mount flags for the + * kernel vfs. When sloppy is non-zero unknown options will be ignored + * otherwise they are considered fatal are copied in to badopt. + */ +static int +parse_options(char *mntopts, unsigned long *mntflags, int sloppy, char *badopt) +{ + int rc = 0, quote = 0; + char *ptr, *opt, *opts; + + opts = strdup(mntopts); + if (opts == NULL) + return (ENOMEM); + + *mntflags = 0; + opt = NULL; + + /* + * Scan through all mount options which must be comma delimited. + * We must be careful to notice regions which are double quoted + * and skip commas in these regions. Each option is then checked + * to determine if it is a known option. + */ + for (ptr = opts; ptr && *ptr; ptr++) { + if (opt == NULL) + opt = ptr; + + if (*ptr == '"') + quote = !quote; + + if (quote) + continue; + + if ((*ptr == ',') || (*ptr == '\0')) { + *ptr = '\0'; + rc = parse_option(opt, mntflags, sloppy); + if (rc) { + strcpy(badopt, opt); + goto out; + } + + opt = NULL; + } + } +out: + free(opts); + return (rc); +} + +/* + * Called when invoked as /sbin/mount.zfs, mount helper for mount(8). */ -#ifdef HAVE_ZPL static int manual_mount(int argc, char **argv) { zfs_handle_t *zhp; - char mountpoint[ZFS_MAXPROPLEN]; + char legacy[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX] = { '\0' }; - int ret; - int c; - int flags = 0; - char *dataset, *path; + char badopt[MNT_LINE_MAX] = { '\0' }; + char *dataset, *mntpoint; + unsigned long mntflags; + int sloppy = 0, fake = 0, verbose = 0; + int rc, c; /* check options */ - while ((c = getopt(argc, argv, ":mo:O")) != -1) { + while ((c = getopt(argc, argv, "sfnvo:h?")) != -1) { switch (c) { + case 's': + sloppy = 1; + break; + case 'f': + fake = 1; + break; + case 'n': + /* Ignored, handled by mount(8) */ + break; + case 'v': + verbose++; + break; case 'o': (void) strlcpy(mntopts, optarg, sizeof (mntopts)); break; - case 'O': - flags |= MS_OVERLAY; - break; - case 'm': - flags |= MS_NOMNTTAB; - break; - case ':': - (void) fprintf(stderr, gettext("missing argument for " - "'%c' option\n"), optopt); - usage(B_FALSE); - break; + case 'h': case '?': - (void) fprintf(stderr, gettext("invalid option '%c'\n"), + (void) fprintf(stderr, gettext("Invalid option '%c'\n"), optopt); - (void) fprintf(stderr, gettext("usage: mount [-o opts] " - "\n")); - return (2); + (void) fprintf(stderr, gettext("Usage: mount.zfs " + "[-sfnv] [-o options] \n")); + return (MOUNT_USAGE); } } @@ -3999,7 +4162,6 @@ manual_unmount(int argc, char **argv) return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE)); } -#endif /* HAVE_ZPL */ static int find_command_idx(char *command, int *idx) @@ -4098,9 +4260,7 @@ main(int argc, char **argv) { int ret; int i = 0; -#ifdef HAVE_ZPL char *progname; -#endif char *cmdname; (void) setlocale(LC_ALL, ""); @@ -4114,20 +4274,16 @@ main(int argc, char **argv) return (1); } -#ifdef HAVE_ZPL /* * This command also doubles as the /etc/fs mount and unmount program. * Determine if we should take this behavior based on argv[0]. */ progname = basename(argv[0]); - if (strcmp(progname, "mount") == 0) { + if (strcmp(progname, "mount.zfs") == 0) { ret = manual_mount(argc, argv); - } else if (strcmp(progname, "umount") == 0) { + } else if (strcmp(progname, "umount.zfs") == 0) { ret = manual_unmount(argc, argv); } else { -#else - { -#endif /* HAVE_ZPL */ /* * Make sure the user has specified some command. */ From 95c4cae39fd77b5b00810eb976c9a6462d86ccd4 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 12:56:10 -0800 Subject: [PATCH 07/75] Disable umount.zfs helper For the moment, the only advantage in registering a umount helper would be to automatically unshare a zfs filesystem. Since under Linux this would be unexpected (but nice) behavior there is no harm in disabling it. This is desirable because the 'zfs unmount' path invokes the system umount. This is done to ensure correct mtab locking but has the side effect that the umount.zfs helper would be called if it exists. By default this helper calls back in to zfs to do the unmount on Solaris which we don't want under Linux. Once libmount is available and we have a safe way to correctly lock and update the /etc/mtab file we can reconsider the need for a umount helper. Using libmount is the prefered solution. --- cmd/zfs/zfs_main.c | 148 ++++++++++++++++++++++++++++++++------------- 1 file changed, 107 insertions(+), 41 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 2aa3e2ef1..e1cca2d91 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -4083,85 +4083,149 @@ manual_mount(int argc, char **argv) else (void) fprintf(stderr, gettext("too many arguments\n")); (void) fprintf(stderr, "usage: mount \n"); - return (2); + return (MOUNT_USAGE); } dataset = argv[0]; - path = argv[1]; + mntpoint = argv[1]; - /* try to open the dataset */ - if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) - return (1); - - (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, - sizeof (mountpoint), NULL, NULL, 0, B_FALSE); - - /* check for legacy mountpoint and complain appropriately */ - ret = 0; - if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) { - if (mount(dataset, path, MS_OPTIONSTR | flags, MNTTYPE_ZFS, - NULL, 0, mntopts, sizeof (mntopts)) != 0) { - (void) fprintf(stderr, gettext("mount failed: %s\n"), - strerror(errno)); - ret = 1; - } - } else { + /* try to open the dataset to access the mount point */ + if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) { (void) fprintf(stderr, gettext("filesystem '%s' cannot be " - "mounted using 'mount -F zfs'\n"), dataset); - (void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' " - "instead.\n"), path); - (void) fprintf(stderr, gettext("If you must use 'mount -F zfs' " - "or /etc/vfstab, use 'zfs set mountpoint=legacy'.\n")); - (void) fprintf(stderr, gettext("See zfs(1M) for more " - "information.\n")); - ret = 1; + "mounted, unable to open the dataset\n"), dataset); + return (MOUNT_USAGE); } - return (ret); + (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy, + sizeof (legacy), NULL, NULL, 0, B_FALSE); + + zfs_close(zhp); + + /* check for legacy mountpoint or util mount option */ + if ((!strcmp(legacy, ZFS_MOUNTPOINT_LEGACY) == 0) && + (strstr(mntopts, MNTOPT_ZFSUTIL) == NULL)) { + (void) fprintf(stderr, gettext("filesystem '%s' cannot be " + "mounted using 'mount -a -t zfs'\n"), dataset); + (void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' " + "instead.\n"), mntpoint); + (void) fprintf(stderr, gettext("If you must use 'mount -a -t " + "zfs' or /etc/fstab, use 'zfs set mountpoint=legacy'.\n")); + (void) fprintf(stderr, gettext("See zfs(8) for more " + "information.\n")); + return (MOUNT_USAGE); + } + + /* validate mount options and set mntflags */ + rc = parse_options(mntopts, &mntflags, sloppy, badopt); + if (rc) { + switch (rc) { + case ENOMEM: + (void) fprintf(stderr, gettext("filesystem '%s' " + "cannot be mounted due to a memory allocation " + "failure\n"), dataset); + return (MOUNT_SYSERR); + case EINVAL: + (void) fprintf(stderr, gettext("filesystem '%s' " + "cannot be mounted of due to the invalid option " + "'%s'\n"), dataset, badopt); + (void) fprintf(stderr, gettext("Use the '-s' option " + "to ignore the bad mount option.\n")); + return (MOUNT_USAGE); + default: + (void) fprintf(stderr, gettext("filesystem '%s' " + "cannot be mounted due to internal error %d\n"), + dataset, rc); + return (MOUNT_SOFTWARE); + } + } + + if (verbose > 2) + printf("mount.zfs: dataset: \"%s\", mountpoint: \"%s\" " + "mountflags: 0x%lx, mountopts: \"%s\"\n", dataset, + mntpoint, mntflags, mntopts); + + /* load the zfs posix layer module (zpl) */ + if (libzfs_load_module("zpl")) { + (void) fprintf(stderr, gettext("filesystem '%s' cannot be " + "mounted without the zpl kernel module\n"), dataset); + (void) fprintf(stderr, gettext("Use 'dmesg' to determine why " + "the module could not be loaded.\n")); + return (MOUNT_SYSERR); + } + + if (!fake) { + rc = mount(dataset, mntpoint, MNTTYPE_ZFS, mntflags, mntopts); + if (rc) { + (void) fprintf(stderr, gettext("filesystem '%s' can" + "not be mounted due to error %d\n"), dataset, rc); + return (MOUNT_USAGE); + } + } + + return (MOUNT_SUCCESS); } +#ifdef HAVE_UNMOUNT_HELPER /* - * Called when invoked as /etc/fs/zfs/umount. Unlike a manual mount, we allow - * unmounts of non-legacy filesystems, as this is the dominant administrative - * interface. + * Called when invoked as /sbin/umount.zfs, mount helper for mount(8). + * Unlike a manual mount, we allow unmounts of non-legacy filesystems, + * as this is the dominant administrative interface. */ static int manual_unmount(int argc, char **argv) { - int flags = 0; + int verbose = 0, flags = 0; int c; /* check options */ - while ((c = getopt(argc, argv, "f")) != -1) { + while ((c = getopt(argc, argv, "nlfvrh?")) != -1) { switch (c) { + case 'n': + /* Ignored, handled by mount(8) */ + break; + case 'l': + flags = MS_DETACH; + break; case 'f': flags = MS_FORCE; break; + case 'v': + verbose++; + break; + case 'r': + /* Remount read-only on umount failure, unsupported */ + (void) fprintf(stderr, gettext("Unsupported option " + "'%c'\n"), optopt); + return (MOUNT_USAGE); + case 'h': case '?': - (void) fprintf(stderr, gettext("invalid option '%c'\n"), + (void) fprintf(stderr, gettext("Invalid option '%c'\n"), optopt); - (void) fprintf(stderr, gettext("usage: unmount [-f] " - "\n")); - return (2); + (void) fprintf(stderr, gettext("Usage: umount.zfs " + "[-nlfvr] \n")); + return (MOUNT_USAGE); } } argc -= optind; argv += optind; - /* check arguments */ + /* check that we only have one argument */ if (argc != 1) { if (argc == 0) - (void) fprintf(stderr, gettext("missing path " + (void) fprintf(stderr, gettext("missing mountpoint " "argument\n")); else (void) fprintf(stderr, gettext("too many arguments\n")); - (void) fprintf(stderr, gettext("usage: unmount [-f] \n")); - return (2); + + (void) fprintf(stderr, gettext("Usage: umount.zfs [-nlfvr] " + "\n")); + return (MOUNT_USAGE); } return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE)); } +#endif /* HAVE_UNMOUNT_HELPER */ static int find_command_idx(char *command, int *idx) @@ -4281,8 +4345,10 @@ main(int argc, char **argv) progname = basename(argv[0]); if (strcmp(progname, "mount.zfs") == 0) { ret = manual_mount(argc, argv); +#ifdef HAVE_UNMOUNT_HELPER } else if (strcmp(progname, "umount.zfs") == 0) { ret = manual_unmount(argc, argv); +#endif /* HAVE_UNMOUNT_HELPER */ } else { /* * Make sure the user has specified some command. From feb46b92a7619a3bb67b925e24184fe70464d261 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 15:47:40 -0800 Subject: [PATCH 08/75] Open up libzfs_run_process/libzfs_load_module Recently helper functions were added to libzfs_util to load a kernel module or execute a process. Initially this functionality was limited to libzfs but it has become clear there will be other consumers. This change opens up the interface so it may be used where appropriate. --- include/libzfs.h | 6 ++++++ lib/libzfs/libzfs_util.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/libzfs.h b/include/libzfs.h index 6752579e8..082b690e9 100644 --- a/include/libzfs.h +++ b/include/libzfs.h @@ -672,6 +672,12 @@ extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *, char *, extern void zfs_nicenum(uint64_t, char *, size_t); extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *); +/* + * Utility functions to run an external process. + */ +int libzfs_run_process(const char *, char **); +int libzfs_load_module(const char *); + /* * Given a device or file, determine if it is part of a pool. */ diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 33c440c48..37dba8d39 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -631,7 +631,7 @@ libzfs_module_loaded(const char *module) return result; } -static int +int libzfs_run_process(const char *path, char *argv[]) { pid_t pid; @@ -657,13 +657,14 @@ libzfs_run_process(const char *path, char *argv[]) return -1; } -static int +int libzfs_load_module(const char *module) { char *argv[4] = {"/sbin/modprobe", "-q", (char *)module, (char *)0}; if (libzfs_module_loaded(module)) return 0; + return libzfs_run_process("/sbin/modprobe", argv); } From 3fb1fcdea167d705e050a0383ec61b95fbe8a0ed Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 16:16:25 -0800 Subject: [PATCH 09/75] Add 'zfs mount' support By design the zfs utility is supposed to handle mounting and unmounting a zfs filesystem. We could allow zfs to do this directly. There are system calls available to mount/umount a filesystem. And there are library calls available to manipulate /etc/mtab. But there are a couple very good reasons not to take this appraoch... for now. Instead of directly calling the system and library calls to (u)mount the filesystem we fork and exec a (u)mount process. The principle reason for this is to delegate the responsibility for locking and updating /etc/mtab to (u)mount(8). This ensures maximum portability and ensures the right locking scheme for your version of (u)mount will be used. If we didn't do this we would have to resort to an autoconf test to determine what locking mechanism is used. The downside to using mount(8) instead of mount(2) is that we lose the exact errno which was returned by the kernel. The return code from mount(8) provides some insight in to what went wrong but it not quite as good. For the moment this is translated as a best guess in to a errno for the higher layers of zfs. In the long term a shared library called libmount is under development which provides a common API to address the locking and errno issues. Once the standard mount utility has been updated to use this library we can then leverage it. Until then this is the only safe solution. http://www.kernel.org/pub/linux/utils/util-linux/libmount-docs/index.html --- cmd/zfs/zfs_main.c | 5 +- lib/libspl/include/sys/mntent.h | 164 ++++++++++++-------------------- lib/libspl/include/sys/mnttab.h | 12 +-- lib/libspl/include/sys/mount.h | 10 +- lib/libzfs/libzfs_mount.c | 110 +++++++++++++++++---- 5 files changed, 169 insertions(+), 132 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index e1cca2d91..2a38cc0fa 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3275,7 +3275,7 @@ share_mount(int op, int argc, char **argv) int flags = 0; /* check options */ - while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:O" : "a")) + while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:" : "a")) != -1) { switch (c) { case 'a': @@ -3298,9 +3298,6 @@ share_mount(int op, int argc, char **argv) append_options(options, optarg); break; - case 'O': - flags |= MS_OVERLAY; - break; case ':': (void) fprintf(stderr, gettext("missing argument for " "'%c' option\n"), optopt); diff --git a/lib/libspl/include/sys/mntent.h b/lib/libspl/include/sys/mntent.h index c0594ca7b..d552c9c17 100644 --- a/lib/libspl/include/sys/mntent.h +++ b/lib/libspl/include/sys/mntent.h @@ -29,114 +29,74 @@ #ifndef _SYS_MNTENT_H #define _SYS_MNTENT_H +#define MNTTYPE_ZFS "zfs" /* ZFS file system */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define MNTTAB "/proc/mounts" -#define VFSTAB "/etc/vfstab" +#define FSTAB "/etc/fstab" #define MNTMAXSTR 128 -#define MNTTYPE_ZFS "zfs" /* ZFS file system */ -#define MNTTYPE_UFS "ufs" /* Unix file system */ -#define MNTTYPE_SMBFS "smbfs" /* SMBFS file system */ -#define MNTTYPE_NFS "nfs" /* NFS file system */ -#define MNTTYPE_NFS3 "nfs3" /* NFS Version 3 file system */ -#define MNTTYPE_NFS4 "nfs4" /* NFS Version 4 file system */ -#define MNTTYPE_CACHEFS "cachefs" /* Cache File System */ -#define MNTTYPE_PCFS "pcfs" /* PC (MSDOS) file system */ -#define MNTTYPE_PC MNTTYPE_PCFS /* Deprecated name; use MNTTYPE_PCFS */ -#define MNTTYPE_LOFS "lofs" /* Loop back file system */ -#define MNTTYPE_LO MNTTYPE_LOFS /* Deprecated name; use MNTTYPE_LOFS */ -#define MNTTYPE_HSFS "hsfs" /* High Sierra (9660) file system */ -#define MNTTYPE_SWAP "swap" /* Swap file system */ -#define MNTTYPE_TMPFS "tmpfs" /* Tmp volatile file system */ -#define MNTTYPE_AUTOFS "autofs" /* Automounter ``file'' system */ -#define MNTTYPE_MNTFS "mntfs" /* In-kernel mnttab */ -#define MNTTYPE_DEV "dev" /* /dev file system */ -#define MNTTYPE_CTFS "ctfs" /* Contract file system */ -#define MNTTYPE_OBJFS "objfs" /* Kernel object file system */ -#define MNTTYPE_SHAREFS "sharefs" /* Kernel sharetab file system */ +#define MOUNT_SUCCESS 0x00 /* Success */ +#define MOUNT_USAGE 0x01 /* Invalid invocation or permissions */ +#define MOUNT_SYSERR 0x02 /* System error (ENOMEM, etc) */ +#define MOUNT_SOFTWARE 0x04 /* Internal mount bug */ +#define MOUNT_USER 0x08 /* Interrupted by user (EINTR) */ +#define MOUNT_FILEIO 0x10 /* Error updating/locking /etc/mtab */ +#define MOUNT_FAIL 0x20 /* Mount failed */ +#define MOUNT_SOMEOK 0x40 /* At least on mount succeeded */ - -#define MNTOPT_RO "ro" /* Read only */ -#define MNTOPT_RW "rw" /* Read/write */ -#define MNTOPT_RQ "rq" /* Read/write with quotas */ -#define MNTOPT_QUOTA "quota" /* Check quotas */ -#define MNTOPT_NOQUOTA "noquota" /* Don't check quotas */ -#define MNTOPT_ONERROR "onerror" /* action to taken on error */ -#define MNTOPT_SOFT "soft" /* Soft mount */ -#define MNTOPT_SEMISOFT "semisoft" /* partial soft, uncommited interface */ -#define MNTOPT_HARD "hard" /* Hard mount */ -#define MNTOPT_SUID "suid" /* Both setuid and devices allowed */ -#define MNTOPT_NOSUID "nosuid" /* Neither setuid nor devices allowed */ -#define MNTOPT_DEVICES "devices" /* Device-special allowed */ -#define MNTOPT_NODEVICES "nodevices" /* Device-special disallowed */ -#define MNTOPT_SETUID "setuid" /* Set uid allowed */ -#define MNTOPT_NOSETUID "nosetuid" /* Set uid not allowed */ -#define MNTOPT_GRPID "grpid" /* SysV-compatible gid on create */ -#define MNTOPT_REMOUNT "remount" /* Change mount options */ -#define MNTOPT_NOSUB "nosub" /* Disallow mounts on subdirs */ -#define MNTOPT_MULTI "multi" /* Do multi-component lookup */ -#define MNTOPT_INTR "intr" /* Allow NFS ops to be interrupted */ -#define MNTOPT_NOINTR "nointr" /* Don't allow interrupted ops */ -#define MNTOPT_PORT "port" /* NFS server IP port number */ -#define MNTOPT_SECURE "secure" /* Secure (AUTH_DES) mounting */ -#define MNTOPT_RSIZE "rsize" /* Max NFS read size (bytes) */ -#define MNTOPT_WSIZE "wsize" /* Max NFS write size (bytes) */ -#define MNTOPT_TIMEO "timeo" /* NFS timeout (1/10 sec) */ -#define MNTOPT_RETRANS "retrans" /* Max retransmissions (soft mnts) */ -#define MNTOPT_ACTIMEO "actimeo" /* Attr cache timeout (sec) */ -#define MNTOPT_ACREGMIN "acregmin" /* Min attr cache timeout (files) */ -#define MNTOPT_ACREGMAX "acregmax" /* Max attr cache timeout (files) */ -#define MNTOPT_ACDIRMIN "acdirmin" /* Min attr cache timeout (dirs) */ -#define MNTOPT_ACDIRMAX "acdirmax" /* Max attr cache timeout (dirs) */ -#define MNTOPT_NOAC "noac" /* Don't cache attributes at all */ -#define MNTOPT_NOCTO "nocto" /* No close-to-open consistency */ -#define MNTOPT_BG "bg" /* Do mount retries in background */ -#define MNTOPT_FG "fg" /* Do mount retries in foreground */ -#define MNTOPT_RETRY "retry" /* Number of mount retries */ -#define MNTOPT_DEV "dev" /* Device id of mounted fs */ -#define MNTOPT_POSIX "posix" /* Get static pathconf for mount */ -#define MNTOPT_MAP "map" /* Automount map */ -#define MNTOPT_DIRECT "direct" /* Automount direct map mount */ -#define MNTOPT_INDIRECT "indirect" /* Automount indirect map mount */ -#define MNTOPT_LLOCK "llock" /* Local locking (no lock manager) */ -#define MNTOPT_IGNORE "ignore" /* Ignore this entry */ -#define MNTOPT_VERS "vers" /* protocol version number indicator */ -#define MNTOPT_PROTO "proto" /* protocol network_id indicator */ -#define MNTOPT_SEC "sec" /* Security flavor indicator */ -#define MNTOPT_SYNCDIR "syncdir" /* Synchronous local directory ops */ -#define MNTOPT_NOSETSEC "nosec" /* Do no allow setting sec attrs */ -#define MNTOPT_NOPRINT "noprint" /* Do not print messages */ -#define MNTOPT_LARGEFILES "largefiles" /* allow large files */ -#define MNTOPT_NOLARGEFILES "nolargefiles" /* don't allow large files */ -#define MNTOPT_FORCEDIRECTIO "forcedirectio" /* Force DirectIO on all files */ -#define MNTOPT_NOFORCEDIRECTIO "noforcedirectio" /* No Force DirectIO */ -#define MNTOPT_DISABLEDIRECTIO "disabledirectio" /* Disable DirectIO ioctls */ -#define MNTOPT_PUBLIC "public" /* Use NFS public file handlee */ -#define MNTOPT_LOGGING "logging" /* enable logging */ -#define MNTOPT_NOLOGGING "nologging" /* disable logging */ +#define MNTOPT_ASYNC "async" /* all I/O is asynchronous */ #define MNTOPT_ATIME "atime" /* update atime for files */ -#define MNTOPT_NOATIME "noatime" /* do not update atime for files */ -#define MNTOPT_GLOBAL "global" /* Cluster-wide global mount */ -#define MNTOPT_NOGLOBAL "noglobal" /* Mount local to single node */ -#define MNTOPT_DFRATIME "dfratime" /* Deferred access time updates */ -#define MNTOPT_NODFRATIME "nodfratime" /* No Deferred access time updates */ -#define MNTOPT_NBMAND "nbmand" /* allow non-blocking mandatory locks */ -#define MNTOPT_NONBMAND "nonbmand" /* deny non-blocking mandatory locks */ -#define MNTOPT_XATTR "xattr" /* enable extended attributes */ -#define MNTOPT_NOXATTR "noxattr" /* disable extended attributes */ +#define MNTOPT_NOATIME "noatime" /* do not update atime for files */ +#define MNTOPT_AUTO "auto" /* automount */ +#define MNTOPT_NOAUTO "noauto" /* do not automount */ +#define MNTOPT_CONTEXT "context" /* selinux context */ +#define MNTOPT_FSCONTEXT "fscontext" /* selinux fscontext */ +#define MNTOPT_DEFCONTEXT "defcontext" /* selinux defcontext */ +#define MNTOPT_ROOTCONTEXT "rootcontext" /* selinux rootcontext */ +#define MNTOPT_DEFAULTS "defaults" /* defaults */ +#define MNTOPT_DEVICES "dev" /* device-special allowed */ +#define MNTOPT_NODEVICES "nodev" /* device-special disallowed */ +#define MNTOPT_DIRATIME "diratime" /* update atime for dirs */ +#define MNTOPT_NODIRATIME "nodiratime" /* do not update atime for dirs */ +#define MNTOPT_DIRSYNC "dirsync" /* do dir updates synchronously */ #define MNTOPT_EXEC "exec" /* enable executables */ #define MNTOPT_NOEXEC "noexec" /* disable executables */ -#define MNTOPT_RESTRICT "restrict" /* restricted autofs mount */ -#define MNTOPT_BROWSE "browse" /* browsable autofs mount */ -#define MNTOPT_NOBROWSE "nobrowse" /* non-browsable autofs mount */ - -#ifdef __cplusplus -} -#endif +#define MNTOPT_GROUP "group" /* allow group mount */ +#define MNTOPT_NOGROUP "nogroup" /* do not allow group mount */ +#define MNTOPT_IVERSION "iversion" /* update inode version */ +#define MNTOPT_NOIVERSION "noiversion" /* do not update inode version */ +#define MNTOPT_NBMAND "mand" /* allow non-blocking mandatory locks */ +#define MNTOPT_NONBMAND "nomand" /* deny non-blocking mandatory locks */ +#define MNTOPT_NETDEV "_netdev" /* network device */ +#define MNTOPT_NOFAIL "nofail" /* no failure */ +#define MNTOPT_RELATIME "relatime" /* allow relative time updates */ +#define MNTOPT_NORELATIME "norelatime" /* do not allow relative time updates */ +#define MNTOPT_DFRATIME "strictatime" /* Deferred access time updates */ +#define MNTOPT_NODFRATIME "nostrictatime" /* No Deferred access time updates */ +#define MNTOPT_SETUID "suid" /* Both setuid and devices allowed */ +#define MNTOPT_NOSETUID "nosuid" /* Neither setuid nor devices allowed */ +#define MNTOPT_OWNER "owner" /* allow owner mount */ +#define MNTOPT_NOOWNER "noowner" /* do not allow owner mount */ +#define MNTOPT_REMOUNT "remount" /* change mount options */ +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_SYNC "sync" /* all I/O is synchronous */ +#define MNTOPT_USER "user" /* allow user mount */ +#define MNTOPT_NOUSER "nouser" /* do not allow user mount */ +#define MNTOPT_USERS "users" /* allow user mount */ +#define MNTOPT_NOUSERS "nousers" /* do not allow user mount */ +#define MNTOPT_SUB "sub" /* allow mounts on subdirs */ +#define MNTOPT_NOSUB "nosub" /* do not allow mounts on subdirs */ +#define MNTOPT_QUIET "quiet" /* quiet mount */ +#define MNTOPT_LOUD "loud" /* verbose mount */ +#define MNTOPT_BIND "bind" /* remount part of a tree */ +#define MNTOPT_RBIND "rbind" /* include subtrees */ +#define MNTOPT_XATTR "user_xattr" /* enable extended attributes */ +#define MNTOPT_NOXATTR "nouser_xattr" /* disable extended attributes */ +#define MNTOPT_COMMENT "comment" /* comment */ +#define MNTOPT_BOOTWAIT "bootwait" +#define MNTOPT_NOBOOTWAIT "nobootwait" +#define MNTOPT_OPTIONAL "optional" +#define MNTOPT_SHOWTHROUGH "showthrough" +#define MNTOPT_ZFSUTIL "zfsutil" /* called by zfs utility */ #endif /* _SYS_MNTENT_H */ diff --git a/lib/libspl/include/sys/mnttab.h b/lib/libspl/include/sys/mnttab.h index 70f144967..a30549a72 100644 --- a/lib/libspl/include/sys/mnttab.h +++ b/lib/libspl/include/sys/mnttab.h @@ -36,14 +36,14 @@ #ifdef MNTTAB #undef MNTTAB -#endif +#endif /* MNTTAB */ -#define MNTTAB "/proc/mounts" -#define MNT_LINE_MAX 1024 +#define MNTTAB "/etc/mtab" +#define MNT_LINE_MAX 1024 -#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */ -#define MNT_TOOMANY 2 /* too many fields in line */ -#define MNT_TOOFEW 3 /* too few fields in line */ +#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */ +#define MNT_TOOMANY 2 /* too many fields in line */ +#define MNT_TOOFEW 3 /* too few fields in line */ struct mnttab { char *mnt_special; diff --git a/lib/libspl/include/sys/mount.h b/lib/libspl/include/sys/mount.h index 144f915d2..f6a67c6a0 100644 --- a/lib/libspl/include/sys/mount.h +++ b/lib/libspl/include/sys/mount.h @@ -42,9 +42,11 @@ #define BLKGETSIZE64 _IOR(0x12, 114, size_t) #endif -#define MS_FORCE MNT_FORCE -#define MS_OVERLAY 32768 -#define MS_NOMNTTAB 0 /* Not supported in Linux */ -#define MS_OPTIONSTR 0 /* Not necessary in Linux */ +#define MS_USERS 0x40000000 +#define MS_OWNER 0x10000000 +#define MS_GROUP 0x08000000 +#define MS_COMMENT 0x02000000 +#define MS_FORCE MNT_FORCE +#define MS_DETACH MNT_DETACH #endif /* _LIBSPL_SYS_MOUNT_H */ diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 9950bf967..75ce3676f 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -258,6 +258,82 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, return (B_TRUE); } +/* + * The filesystem is mounted by invoking the system mount utility rather + * than by the system call mount(2). This ensures that the /etc/mtab + * file is correctly locked for the update. Performing our own locking + * and /etc/mtab update requires making an unsafe assumption about how + * the mount utility performs its locking. Unfortunately, this also means + * in the case of a mount failure we do not have the exact errno. We must + * make due with return value from the mount process. + * + * In the long term a shared library called libmount is under development + * which provides a common API to address the locking and errno issues. + * Once the standard mount utility has been updated to use this library + * we can add an autoconf check to conditionally use it. + * + * http://www.kernel.org/pub/linux/utils/util-linux/libmount-docs/index.html + */ + +static int +do_mount(const char *src, const char *mntpt, char *opts) +{ + char *argv[8] = { + "/bin/mount", + "-t", MNTTYPE_ZFS, + "-o", opts, + (char *)src, + (char *)mntpt, + (char *)NULL }; + int rc; + + /* Return only the most critical mount error */ + rc = libzfs_run_process(argv[0], argv); + if (rc) { + if (rc & MOUNT_FILEIO) + return EIO; + if (rc & MOUNT_USER) + return EINTR; + if (rc & MOUNT_SOFTWARE) + return EPIPE; + if (rc & MOUNT_SYSERR) + return EAGAIN; + if (rc & MOUNT_USAGE) + return EINVAL; + + return ENXIO; /* Generic error */ + } + + return 0; +} + +static int +do_unmount(const char *mntpt, int flags) +{ + char force_opt[] = "-f"; + char lazy_opt[] = "-l"; + char *argv[7] = { + "/bin/umount", + "-t", MNTTYPE_ZFS, + NULL, NULL, NULL, NULL }; + int rc, count = 3; + + if (flags & MS_FORCE) { + argv[count] = force_opt; + count++; + } + + if (flags & MS_DETACH) { + argv[count] = lazy_opt; + count++; + } + + argv[count] = (char *)mntpt; + rc = libzfs_run_process(argv[0], argv); + + return (rc ? EINVAL : 0); +} + /* * Mount the given filesystem. */ @@ -268,9 +344,10 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; + int rc; if (options == NULL) - mntopts[0] = '\0'; + (void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts)); else (void) strlcpy(mntopts, options, sizeof (mntopts)); @@ -278,7 +355,12 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) * If the pool is imported read-only then all mounts must be read-only */ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) - flags |= MS_RDONLY; + (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); + + /* + * Append zfsutil option so the mount helper allow the mount + */ + strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); #ifdef HAVE_LIBSELINUX if (is_selinux_enabled()) @@ -302,12 +384,9 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) /* * Determine if the mountpoint is empty. If so, refuse to perform the - * mount. We don't perform this check if MS_OVERLAY is specified, which - * would defeat the point. We also avoid this check if 'remount' is - * specified. + * mount. We don't perform this check if 'remount' is specified. */ - if ((flags & MS_OVERLAY) == 0 && - strstr(mntopts, MNTOPT_REMOUNT) == NULL && + if (strstr(mntopts, MNTOPT_REMOUNT) == NULL && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); @@ -316,20 +395,20 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) } /* perform the mount */ - if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, - MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { + rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts); + if (rc) { /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ - if (errno == EBUSY) { + if (rc == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); - } else if (errno == EPERM) { + } else if (rc == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); - } else if (errno == ENOTSUP) { + } else if (rc == ENOTSUP) { char buf[256]; int spa_version; @@ -342,7 +421,7 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); } else { - zfs_error_aux(hdl, strerror(errno)); + zfs_error_aux(hdl, strerror(rc)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), @@ -350,8 +429,7 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) } /* add the mounted entry into our cache */ - libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, - mntopts); + libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); } @@ -361,7 +439,7 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) static int unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) { - if (umount2(mountpoint, flags) != 0) { + if (do_unmount(mountpoint, flags) != 0) { zfs_error_aux(hdl, strerror(errno)); return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), From c5d915f4237bbd1f5623b5044a1924a3cb91852b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 13:47:30 -0800 Subject: [PATCH 10/75] Minimal libshare infrastructure ZFS even under Solaris does not strictly require libshare to be available. The current implementation attempts to dlopen() the library to access the needed symbols. If this fails libshare support is simply disabled. This means that on Linux we only need the most minimal libshare implementation. In fact just enough to prevent the build from failing. Longer term we can decide if we want to implement a libshare library like Solaris. At best this would be an abstraction layer between ZFS and NFS/SMB. Alternately, we can drop libshare entirely and directly integrate ZFS with Linux's NFS/SMB. Finally the bare bones user-libshare.m4 test was dropped. If we do decide to implement libshare at some point it will surely be as part of this package so the check is not needed. --- Makefile.in | 1 - cmd/Makefile.in | 1 - cmd/zdb/Makefile.in | 1 - cmd/zfs/Makefile.in | 1 - cmd/zinject/Makefile.in | 1 - cmd/zpios/Makefile.in | 1 - cmd/zpool/Makefile.in | 1 - cmd/zpool_id/Makefile.in | 1 - cmd/zpool_layout/Makefile.in | 1 - cmd/ztest/Makefile.in | 1 - config/user-libshare.m4 | 8 -- config/user.m4 | 1 - configure | 150 -------------------- etc/Makefile.in | 1 - include/Makefile.in | 1 - include/sys/Makefile.in | 1 - include/sys/fm/Makefile.in | 1 - include/sys/fm/fs/Makefile.in | 1 - include/sys/fs/Makefile.in | 1 - lib/Makefile.in | 1 - lib/libavl/Makefile.in | 1 - lib/libefi/Makefile.in | 1 - lib/libnvpair/Makefile.in | 1 - lib/libspl/Makefile.in | 1 - lib/libspl/asm-generic/Makefile.in | 1 - lib/libspl/asm-i386/Makefile.in | 1 - lib/libspl/asm-x86_64/Makefile.in | 1 - lib/libspl/include/Makefile.in | 1 - lib/libspl/include/ia32/Makefile.in | 1 - lib/libspl/include/ia32/sys/Makefile.in | 1 - lib/libspl/include/libshare.h | 18 ++- lib/libspl/include/rpc/Makefile.in | 1 - lib/libspl/include/sys/Makefile.in | 1 - lib/libspl/include/sys/dktp/Makefile.in | 1 - lib/libspl/include/sys/sysevent/Makefile.in | 1 - lib/libspl/include/util/Makefile.in | 1 - lib/libunicode/Makefile.in | 1 - lib/libuutil/Makefile.in | 1 - lib/libzfs/Makefile.in | 1 - lib/libzfs/libzfs_mount.c | 35 ++--- lib/libzpool/Makefile.in | 1 - man/Makefile.in | 1 - man/man8/Makefile.in | 1 - scripts/Makefile.in | 1 - scripts/zpios-profile/Makefile.in | 1 - scripts/zpios-test/Makefile.in | 1 - scripts/zpool-config/Makefile.in | 1 - scripts/zpool-layout/Makefile.in | 1 - zfs_config.h.in | 3 - 49 files changed, 24 insertions(+), 234 deletions(-) delete mode 100644 config/user-libshare.m4 diff --git a/Makefile.in b/Makefile.in index 09708bf4a..0d10478d8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -77,7 +77,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index bed295156..016045a6a 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -62,7 +62,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index b84eb2c0f..ce17224a1 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index 6bd1f3fbd..654a3814e 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index c2598673e..daced68ab 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index c30a3e04d..69747f368 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index b628756bd..a6f96f7be 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index 932bc25f3..5d32e8106 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index 9b1b5ebae..ef53493a5 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index 3b4e7c45e..ec16a7394 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -65,7 +65,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/config/user-libshare.m4 b/config/user-libshare.m4 deleted file mode 100644 index 3b92bbaa5..000000000 --- a/config/user-libshare.m4 +++ /dev/null @@ -1,8 +0,0 @@ -dnl # -dnl # Check for libshare -dnl # -AC_DEFUN([ZFS_AC_CONFIG_USER_LIBSHARE], [ - AC_CHECK_LIB([share], [sa_init], - [AC_DEFINE([HAVE_LIBSHARE], 1, - [Define to 1 if 'libshare' library available])]) -]) diff --git a/config/user.m4 b/config/user.m4 index 6f0276937..a79deefe8 100644 --- a/config/user.m4 +++ b/config/user.m4 @@ -3,7 +3,6 @@ dnl # Default ZFS user configuration dnl # AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_ARCH - ZFS_AC_CONFIG_USER_LIBSHARE ZFS_AC_CONFIG_USER_IOCTL ZFS_AC_CONFIG_USER_ZLIB ZFS_AC_CONFIG_USER_LIBUUID diff --git a/configure b/configure index 48bf4cba1..d96270472 100755 --- a/configure +++ b/configure @@ -13849,81 +13849,6 @@ $as_echo_n "checking for target asm dir... " >&6; } $as_echo "$TARGET_ASM_DIR" >&6; } - { $as_echo "$as_me:$LINENO: checking for sa_init in -lshare" >&5 -$as_echo_n "checking for sa_init in -lshare... " >&6; } -if test "${ac_cv_lib_share_sa_init+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lshare $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sa_init (); -int -main () -{ -return sa_init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_share_sa_init=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_share_sa_init=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_share_sa_init" >&5 -$as_echo "$ac_cv_lib_share_sa_init" >&6; } -if test "x$ac_cv_lib_share_sa_init" = x""yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBSHARE 1 -_ACEOF - -fi - - - { $as_echo "$as_me:$LINENO: checking for ioctl()" >&5 $as_echo_n "checking for ioctl()... " >&6; } cat >conftest.$ac_ext <<_ACEOF @@ -17446,81 +17371,6 @@ $as_echo_n "checking for target asm dir... " >&6; } $as_echo "$TARGET_ASM_DIR" >&6; } - { $as_echo "$as_me:$LINENO: checking for sa_init in -lshare" >&5 -$as_echo_n "checking for sa_init in -lshare... " >&6; } -if test "${ac_cv_lib_share_sa_init+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lshare $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sa_init (); -int -main () -{ -return sa_init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_share_sa_init=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_share_sa_init=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_share_sa_init" >&5 -$as_echo "$ac_cv_lib_share_sa_init" >&6; } -if test "x$ac_cv_lib_share_sa_init" = x""yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBSHARE 1 -_ACEOF - -fi - - - { $as_echo "$as_me:$LINENO: checking for ioctl()" >&5 $as_echo_n "checking for ioctl()... " >&6; } cat >conftest.$ac_ext <<_ACEOF diff --git a/etc/Makefile.in b/etc/Makefile.in index eb8ad9570..4d3939461 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/include/Makefile.in b/include/Makefile.in index 7a1f40ab5..851bd8a12 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index d3985cc8e..2e8af81de 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index b27565995..4099398b3 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index e8d289abe..ddad52360 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index d1ee3b2d8..903b08d37 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 18ff05229..d607102b1 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -62,7 +62,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 500846a77..91590932a 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 1f4409066..7839c1354 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index e1027d51c..0bafbab1c 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 385a567c6..8aa947ab4 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 162c386ca..0a8ff7c25 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index 9a26bb4d4..6ef74836a 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index a00f235b7..5c1aeafee 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index 360560052..0f2a688ae 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index a9f80cde8..d3a8f6fa2 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -62,7 +62,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index fb0fe3f8c..5f7e05fdd 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/libshare.h b/lib/libspl/include/libshare.h index afbdf5b05..f1fbfad2b 100644 --- a/lib/libspl/include/libshare.h +++ b/lib/libspl/include/libshare.h @@ -23,12 +23,20 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -/* - * basic API declarations for share management - */ - #ifndef _LIBSPL_LIBSHARE_H #define _LIBSPL_LIBSHARE_H +typedef void *sa_handle_t; /* opaque handle to access core functions */ +typedef void *sa_group_t; +typedef void *sa_share_t; + +/* API Initialization */ +#define SA_INIT_SHARE_API 0x0001 /* init share specific interface */ +#define SA_INIT_CONTROL_API 0x0002 /* init control specific interface */ + +/* Error values */ +#define SA_OK 0 +#define SA_NO_MEMORY 2 /* no memory for data structures */ +#define SA_CONFIG_ERR 6 /* system configuration error */ + #endif /* _LIBSPL_LIBSHARE_H */ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 1fd162a47..850f04542 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index 0746ded39..f8f8294d9 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index 499081af2..19b0f3bcb 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 0a9c6d186..96af2d3b1 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index 27aa363f3..bfaec7a2e 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index 5daee2b73..fb075e8bf 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index 1a28249ae..32d6a7404 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index c8b500466..cad8e6c33 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 75ce3676f..42036a44b 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -121,20 +121,21 @@ zfs_share_proto_t share_all_proto[] = { }; /* - * Search the sharetab for the given mountpoint and protocol, returning + * Search for NFS and SMB exports for the given mountpoint and protocol, returning * a zfs_share_type_t value. */ static zfs_share_type_t is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto) { char buf[MAXPATHLEN], *tab; - char *ptr; if (hdl->libzfs_sharetab == NULL) return (SHARED_NOT_SHARED); (void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET); + /* Search /etc/exports for NFS exports */ + /* FIXME: Assumes the file is tab delimited. */ while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) { /* the mountpoint is the first entry on each line */ @@ -143,31 +144,15 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto) *tab = '\0'; if (strcmp(buf, mountpoint) == 0) { - /* - * the protocol field is the third field - * skip over second field - */ - ptr = ++tab; - if ((tab = strchr(ptr, '\t')) == NULL) - continue; - ptr = ++tab; - if ((tab = strchr(ptr, '\t')) == NULL) - continue; - *tab = '\0'; - if (strcmp(ptr, - proto_table[proto].p_name) == 0) { - switch (proto) { - case PROTO_NFS: - return (SHARED_NFS); - case PROTO_SMB: - return (SHARED_SMB); - default: - return (0); - } - } + if (proto == PROTO_NFS) + return (SHARED_NFS); + else + return (SHARED_NOT_SHARED); } } + /* XXX: Search /etc/samba/smb.conf for SMB exports, return SHARED_SMB */ + return (SHARED_NOT_SHARED); } @@ -808,10 +793,12 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) return (0); if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) { +#ifdef HAVE_SHARE (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED, dgettext(TEXT_DOMAIN, "cannot share '%s': %s"), zfs_get_name(zhp), _sa_errorstr != NULL ? _sa_errorstr(ret) : ""); +#endif /* HAVE_SHARE */ return (-1); } diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 421e55cc2..209b8594e 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -64,7 +64,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index 47a16fe64..3dbed3094 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -62,7 +62,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index 0a96d97bd..f3cd85637 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -62,7 +62,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 076fc6c28..6653bf385 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index fe89e1d00..fd95774cb 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index 09f0503c7..fcb6dfedd 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index 71ef3c5f2..da8b65e7c 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index d270230fe..dde427b3f 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -63,7 +63,6 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/user-frame-larger-than.m4 \ $(top_srcdir)/config/user-ioctl.m4 \ $(top_srcdir)/config/user-libblkid.m4 \ - $(top_srcdir)/config/user-libshare.m4 \ $(top_srcdir)/config/user-libuuid.m4 \ $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ $(top_srcdir)/config/user-selinux.m4 \ diff --git a/zfs_config.h.in b/zfs_config.h.in index e1532f635..f8e218259 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -87,9 +87,6 @@ /* Define if you have selinux */ #undef HAVE_LIBSELINUX -/* Define to 1 if 'libshare' library available */ -#undef HAVE_LIBSHARE - /* Define if you have libuuid */ #undef HAVE_LIBUUID From 9a616b5d17185c7fa5cd0d39ff8bc101cad8466d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 15:43:37 -0800 Subject: [PATCH 11/75] Documentation updates Minor Linux specific documentation updates to the comments and man pages. --- cmd/zfs/zfs_main.c | 18 +++++++++--------- cmd/zinject/translate.c | 2 +- lib/libzfs/libzfs_dataset.c | 4 ++-- lib/libzfs/libzfs_mount.c | 2 +- man/man8/zfs.8 | 6 +++--- module/zfs/zfs_ctldir.c | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 2a38cc0fa..8d75d2a45 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3365,7 +3365,7 @@ share_mount(int op, int argc, char **argv) } /* - * When mount is given no arguments, go through /etc/mnttab and + * When mount is given no arguments, go through /etc/mtab and * display any active ZFS mounts. We hide any snapshots, since * they are controlled automatically. */ @@ -3453,7 +3453,7 @@ unshare_unmount_compare(const void *larg, const void *rarg, void *unused) /* * Convenience routine used by zfs_do_umount() and manual_unmount(). Given an - * absolute path, find the entry /etc/mnttab, verify that its a ZFS filesystem, + * absolute path, find the entry /etc/mtab, verify that its a ZFS filesystem, * and unmount it appropriately. */ static int @@ -3467,7 +3467,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) ino_t path_inode; /* - * Search for the path in /etc/mnttab. Rather than looking for the + * Search for the path in /etc/mtab. Rather than looking for the * specific path, which can be fooled by non-standard paths (i.e. ".." * or "//"), we stat() the path and search for the corresponding * (major,minor) device pair. @@ -3494,7 +3494,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) "currently mounted\n"), cmdname, path); return (1); } - (void) fprintf(stderr, gettext("warning: %s not in mnttab\n"), + (void) fprintf(stderr, gettext("warning: %s not in mtab\n"), path); if ((ret = umount2(path, flags)) != 0) (void) fprintf(stderr, gettext("%s: %s\n"), path, @@ -3536,8 +3536,8 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) strcmp(smbshare_prop, "off") == 0) { (void) fprintf(stderr, gettext("cannot unshare " "'%s': legacy share\n"), path); - (void) fprintf(stderr, gettext("use " - "unshare(1M) to unshare this filesystem\n")); + (void) fprintf(stderr, gettext("use exportfs(8) " + "or smbcontrol(1) to unshare this filesystem\n")); } else if (!zfs_is_shared(zhp)) { (void) fprintf(stderr, gettext("cannot unshare '%s': " "not currently shared\n"), path); @@ -3556,7 +3556,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) (void) fprintf(stderr, gettext("cannot unmount " "'%s': legacy mountpoint\n"), zfs_get_name(zhp)); - (void) fprintf(stderr, gettext("use umount(1M) " + (void) fprintf(stderr, gettext("use umount(8) " "to unmount this filesystem\n")); } else { ret = zfs_unmountall(zhp, flags); @@ -3606,8 +3606,8 @@ unshare_unmount(int op, int argc, char **argv) /* * We could make use of zfs_for_each() to walk all datasets in * the system, but this would be very inefficient, especially - * since we would have to linearly search /etc/mnttab for each - * one. Instead, do one pass through /etc/mnttab looking for + * since we would have to linearly search /etc/mtab for each + * one. Instead, do one pass through /etc/mtab looking for * zfs entries and call zfs_unmount() for each one. * * Things get a little tricky if the administrator has created diff --git a/cmd/zinject/translate.c b/cmd/zinject/translate.c index 996075283..160786641 100644 --- a/cmd/zinject/translate.c +++ b/cmd/zinject/translate.c @@ -115,7 +115,7 @@ parse_pathname(const char *inpath, char *dataset, char *relpath, } if ((fp = fopen(MNTTAB, "r")) == NULL) { - (void) fprintf(stderr, "cannot open /etc/mnttab\n"); + (void) fprintf(stderr, "cannot open /etc/mtab\n"); return (-1); } diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index d876e5d1f..d4b59f2ce 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1600,7 +1600,7 @@ zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie) * zfs_prop_get_int() are built using this interface. * * Certain properties can be overridden using 'mount -o'. In this case, scan - * the contents of the /etc/mnttab entry, searching for the appropriate options. + * the contents of the /etc/mtab entry, searching for the appropriate options. * If they differ from the on-disk values, report the current values and mark * the source "temporary". */ @@ -1658,7 +1658,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, /* * Because looking up the mount options is potentially expensive - * (iterating over all of /etc/mnttab), we defer its calculation until + * (iterating over all of /etc/mtab), we defer its calculation until * we're looking up a property which requires its presence. */ if (!zhp->zfs_mntcheck && diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 42036a44b..977b2ee31 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -1212,7 +1212,7 @@ mountpoint_compare(const void *a, const void *b) * Unshare and unmount all datasets within the given pool. We don't want to * rely on traversing the DSL to discover the filesystems within the pool, * because this may be expensive (if not all of them are mounted), and can fail - * arbitrarily (on I/O error, for example). Instead, we walk /etc/mnttab and + * arbitrarily (on I/O error, for example). Instead, we walk /etc/mtab and * gather all the filesystems that are currently mounted. */ int diff --git a/man/man8/zfs.8 b/man/man8/zfs.8 index ecde1d98a..a7404e659 100644 --- a/man/man8/zfs.8 +++ b/man/man8/zfs.8 @@ -302,19 +302,19 @@ The clone parent-child dependency relationship can be reversed by using the \fBp .SS "Mount Points" .sp .LP -Creating a \fBZFS\fR file system is a simple operation, so the number of file systems per system is likely to be numerous. To cope with this, \fBZFS\fR automatically manages mounting and unmounting file systems without the need to edit the \fB/etc/vfstab\fR file. All automatically managed file systems are mounted by \fBZFS\fR at boot time. +Creating a \fBZFS\fR file system is a simple operation, so the number of file systems per system is likely to be numerous. To cope with this, \fBZFS\fR automatically manages mounting and unmounting file systems without the need to edit the \fB/etc/fstab\fR file. All automatically managed file systems are mounted by \fBZFS\fR at boot time. .sp .LP By default, file systems are mounted under \fB/\fIpath\fR\fR, where \fIpath\fR is the name of the file system in the \fBZFS\fR namespace. Directories are created and destroyed as needed. .sp .LP -A file system can also have a mount point set in the \fBmountpoint\fR property. This directory is created as needed, and \fBZFS\fR automatically mounts the file system when the \fBzfs mount -a\fR command is invoked (without editing \fB/etc/vfstab\fR). The \fBmountpoint\fR property can be inherited, so if \fBpool/home\fR has a mount point of \fB/export/stuff\fR, then \fBpool/home/user\fR automatically inherits a mount point of \fB/export/stuff/user\fR. +A file system can also have a mount point set in the \fBmountpoint\fR property. This directory is created as needed, and \fBZFS\fR automatically mounts the file system when the \fBzfs mount -a\fR command is invoked (without editing \fB/etc/fstab\fR). The \fBmountpoint\fR property can be inherited, so if \fBpool/home\fR has a mount point of \fB/export/stuff\fR, then \fBpool/home/user\fR automatically inherits a mount point of \fB/export/stuff/user\fR. .sp .LP A file system \fBmountpoint\fR property of \fBnone\fR prevents the file system from being mounted. .sp .LP -If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/vfstab\fR). If a file system's mount point is set to \fBlegacy\fR, \fBZFS\fR makes no attempt to manage the file system, and the administrator is responsible for mounting and unmounting the file system. +If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/fstab\fR). If a file system's mount point is set to \fBlegacy\fR, \fBZFS\fR makes no attempt to manage the file system, and the administrator is responsible for mounting and unmounting the file system. .SS "Zones" .sp .LP diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c index 51b12a1d5..b7dac213f 100644 --- a/module/zfs/zfs_ctldir.c +++ b/module/zfs/zfs_ctldir.c @@ -31,7 +31,7 @@ * does not actually exist on disk. * * For 'snapshot', we don't want to have all snapshots always mounted, because - * this would take up a huge amount of space in /etc/mnttab. We have three + * this would take up a huge amount of space in /etc/mtab. We have three * types of objects: * * ctldir ------> snapshotdir -------> snapshot From b4ead57cfb410247eee4d2a8a6e488cf4542ac77 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 16 Dec 2010 15:11:40 -0800 Subject: [PATCH 12/75] Remove HAVE_ZPL from commands and libraries Thanks to the previous few commits we can now build all of the user space commands and libraries with support for the zpl. --- cmd/zfs/zfs_main.c | 34 ----------------------- cmd/zinject/zinject.c | 4 --- cmd/zpool/zpool_main.c | 10 ------- lib/libzfs/libzfs_changelist.c | 12 -------- lib/libzfs/libzfs_dataset.c | 26 ----------------- lib/libzfs/libzfs_mount.c | 51 ---------------------------------- lib/libzfs/libzfs_util.c | 2 -- 7 files changed, 139 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 8d75d2a45..d27fcbf46 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -318,7 +318,6 @@ safe_malloc(size_t size) return (data); } -#ifdef HAVE_ZPL static char * safe_strdup(char *str) { @@ -329,7 +328,6 @@ safe_strdup(char *str) return (dupstr); } -#endif /* HAVE_ZPL */ /* * Callback routine that will print out information for each of @@ -497,7 +495,6 @@ parse_depth(char *opt, int *flags) #define PROGRESS_DELAY 2 /* seconds */ -#ifdef HAVE_ZPL static char *pt_reverse = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; static time_t pt_begin; static char *pt_header = NULL; @@ -549,7 +546,6 @@ finish_progress(char *done) free(pt_header); pt_header = NULL; } -#endif /* HAVE_ZPL */ /* * zfs clone [-p] [-o prop=value] ... @@ -631,7 +627,6 @@ zfs_do_clone(int argc, char **argv) ret = zfs_clone(zhp, argv[1], props); /* create the mountpoint if necessary */ -#ifdef HAVE_ZPL if (ret == 0) { zfs_handle_t *clone; @@ -643,7 +638,6 @@ zfs_do_clone(int argc, char **argv) zfs_close(clone); } } -#endif /* HAVE_ZPL */ zfs_close(zhp); nvlist_free(props); @@ -831,7 +825,6 @@ zfs_do_create(int argc, char **argv) * verbose error message to let the user know that their filesystem was * in fact created, even if we failed to mount or share it. */ -#ifdef HAVE_ZPL if (canmount == ZFS_CANMOUNT_ON) { if (zfs_mount(zhp, NULL, 0) != 0) { (void) fprintf(stderr, gettext("filesystem " @@ -843,7 +836,6 @@ zfs_do_create(int argc, char **argv) ret = 1; } } -#endif /* HAVE_ZPL */ error: if (zhp) @@ -2340,7 +2332,6 @@ typedef struct rollback_cbdata { * 'cb_dependent' is set, then this is a dependent and we should report it * without checking the transaction group. */ -#ifdef HAVE_ZPL static int rollback_check(zfs_handle_t *zhp, void *data) { @@ -2400,12 +2391,10 @@ rollback_check(zfs_handle_t *zhp, void *data) zfs_close(zhp); return (0); } -#endif /* HAVE_ZPL */ static int zfs_do_rollback(int argc, char **argv) { -#ifdef HAVE_ZPL int ret; int c; boolean_t force = B_FALSE; @@ -2487,9 +2476,6 @@ out: return (0); else return (1); -#else - return ENOSYS; -#endif /*HAVE_ZPL*/ } /* @@ -2955,7 +2941,6 @@ zfs_do_release(int argc, char **argv) #define SPINNER_TIME 3 /* seconds */ #define MOUNT_TIME 5 /* seconds */ -#ifdef HAVE_ZPL static int get_one_dataset(zfs_handle_t *zhp, void *data) { @@ -3400,7 +3385,6 @@ share_mount(int op, int argc, char **argv) return (ret); } -#endif /* HAVE_ZPL */ /* * zfs mount -a [nfs] @@ -3411,11 +3395,7 @@ share_mount(int op, int argc, char **argv) static int zfs_do_mount(int argc, char **argv) { -#ifdef HAVE_ZPL return (share_mount(OP_MOUNT, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* @@ -3427,14 +3407,9 @@ zfs_do_mount(int argc, char **argv) static int zfs_do_share(int argc, char **argv) { -#ifdef HAVE_ZPL return (share_mount(OP_SHARE, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } -#ifdef HAVE_ZPL typedef struct unshare_unmount_node { zfs_handle_t *un_zhp; char *un_mountp; @@ -3818,7 +3793,6 @@ unshare_unmount(int op, int argc, char **argv) return (ret); } -#endif /* HAVE_ZPL */ /* * zfs unmount -a @@ -3829,11 +3803,7 @@ unshare_unmount(int op, int argc, char **argv) static int zfs_do_unmount(int argc, char **argv) { -#ifdef HAVE_ZPL return (unshare_unmount(OP_MOUNT, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* @@ -3845,11 +3815,7 @@ zfs_do_unmount(int argc, char **argv) static int zfs_do_unshare(int argc, char **argv) { -#ifdef HAVE_ZPL return (unshare_unmount(OP_SHARE, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* ARGSUSED */ diff --git a/cmd/zinject/zinject.c b/cmd/zinject/zinject.c index e76e626fa..d584eadd8 100644 --- a/cmd/zinject/zinject.c +++ b/cmd/zinject/zinject.c @@ -951,20 +951,16 @@ main(int argc, char **argv) if (dataset[0] != '\0' && domount) { if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL) return (1); -#ifdef HAVE_ZPL if (zfs_unmount(zhp, NULL, 0) != 0) return (1); -#endif /* HAVE_ZPL */ } record.zi_error = error; ret = register_handler(pool, flags, &record, quiet); -#ifdef HAVE_ZPL if (dataset[0] != '\0' && domount) ret = (zfs_mount(zhp, NULL, 0) != 0); -#endif /* HAVE_ZPL */ libzfs_fini(g_zfs); diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 1e9b3b69e..bad4e2a4f 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -716,9 +716,7 @@ zpool_do_create(int argc, char **argv) (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { char buf[MAXPATHLEN]; -#ifdef HAVE_ZPL DIR *dirp; -#endif if (mountpoint && mountpoint[0] != '/') { (void) fprintf(stderr, gettext("invalid mountpoint " @@ -743,7 +741,6 @@ zpool_do_create(int argc, char **argv) mountpoint); } -#ifdef HAVE_ZPL if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { (void) fprintf(stderr, gettext("mountpoint '%s' : " "%s\n"), buf, strerror(errno)); @@ -766,7 +763,6 @@ zpool_do_create(int argc, char **argv) goto errout; } } -#endif /* HAVE_ZPL */ } if (dryrun) { @@ -797,12 +793,8 @@ zpool_do_create(int argc, char **argv) zfs_prop_to_name( ZFS_PROP_MOUNTPOINT), mountpoint) == 0); -#ifdef HAVE_ZPL if (zfs_mount(pool, NULL, 0) == 0) ret = zfs_shareall(pool); -#else - ret = 0; -#endif /* HAVE_ZPL */ zfs_close(pool); } } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { @@ -1579,14 +1571,12 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) return (1); -#if HAVE_ZPL if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && !(flags & ZFS_IMPORT_ONLY) && zpool_enable_datasets(zhp, mntopts, 0) != 0) { zpool_close(zhp); return (1); } -#endif /* HAVE_ZPL */ zpool_close(zhp); return (0); diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c index 6f067d563..0bcfc0423 100644 --- a/lib/libzfs/libzfs_changelist.c +++ b/lib/libzfs/libzfs_changelist.c @@ -93,7 +93,6 @@ struct prop_changelist { int changelist_prefix(prop_changelist_t *clp) { -#ifdef HAVE_ZPL prop_changenode_t *cn; int ret = 0; @@ -142,9 +141,6 @@ changelist_prefix(prop_changelist_t *clp) (void) changelist_postfix(clp); return (ret); -#else - return 0; -#endif /* HAVE_ZPL */ } /* @@ -159,7 +155,6 @@ changelist_prefix(prop_changelist_t *clp) int changelist_postfix(prop_changelist_t *clp) { -#ifdef HAVE_ZPL prop_changenode_t *cn; char shareopts[ZFS_MAXPROPLEN]; int errors = 0; @@ -260,9 +255,6 @@ changelist_postfix(prop_changelist_t *clp) } return (errors ? -1 : 0); -#else - return 0; -#endif /* HAVE_ZPL */ } /* @@ -325,7 +317,6 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst) int changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto) { -#ifdef HAVE_ZPL prop_changenode_t *cn; int ret = 0; @@ -340,9 +331,6 @@ changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto) } return (ret); -#else - return 0; -#endif } /* diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index d4b59f2ce..378bbc7b1 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -995,7 +995,6 @@ badlabel: /*FALLTHRU*/ -#ifdef HAVE_ZPL case ZFS_PROP_SHARESMB: case ZFS_PROP_SHARENFS: /* @@ -1106,7 +1105,6 @@ badlabel: } break; -#endif /* HAVE_ZPL */ case ZFS_PROP_UTF8ONLY: chosen_utf = (int)intval; break; @@ -2745,7 +2743,6 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen) goto ancestorerr; } -#ifdef HAVE_ZPL if (zfs_mount(h, NULL, 0) != 0) { opname = dgettext(TEXT_DOMAIN, "mount"); goto ancestorerr; @@ -2755,7 +2752,6 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen) opname = dgettext(TEXT_DOMAIN, "share"); goto ancestorerr; } -#endif /* HAVE_ZPL */ zfs_close(h); } @@ -4037,28 +4033,6 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received) return (0); } -#ifdef HAVE_ZPL -int -zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path, - char *resource, void *export, void *sharetab, - int sharemax, zfs_share_op_t operation) -{ - zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 }; - int error; - - (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); - (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value)); - if (resource) - (void) strlcpy(zc.zc_string, resource, sizeof (zc.zc_string)); - zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab; - zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export; - zc.zc_share.z_sharetype = operation; - zc.zc_share.z_sharemax = sharemax; - error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc); - return (error); -} -#endif /* HAVE_ZPL */ - void zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props) { diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 977b2ee31..f55b16bdc 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -84,7 +84,6 @@ #include #define MAXISALEN 257 /* based on sysinfo(2) man page */ -#ifdef HAVE_ZPL static int zfs_share_proto(zfs_handle_t *, zfs_share_proto_t *); zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **, zfs_share_proto_t); @@ -1343,53 +1342,3 @@ out: return (ret); } - -#else /* HAVE_ZPL */ - -int -zfs_unshare_iscsi(zfs_handle_t *zhp) -{ - return 0; -} - -int -zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags) -{ - return 0; -} - -void -remove_mountpoint(zfs_handle_t *zhp) { - return; -} - -boolean_t -is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where) -{ - return B_FALSE; -} - -boolean_t -zfs_is_mounted(zfs_handle_t *zhp, char **where) -{ - return is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where); -} - -boolean_t -zfs_is_shared(zfs_handle_t *zhp) -{ - return B_FALSE; -} - -int -zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags) -{ - return B_FALSE; -} - -int -zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) -{ - return B_FALSE; -} -#endif /* HAVE_ZPL */ diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 37dba8d39..163cd1671 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -727,9 +727,7 @@ libzfs_fini(libzfs_handle_t *hdl) #endif if (hdl->libzfs_sharetab) (void) fclose(hdl->libzfs_sharetab); -#ifdef HAVE_ZPL zfs_uninit_libshare(hdl); -#endif if (hdl->libzfs_log_str) (void) free(hdl->libzfs_log_str); zpool_free_handles(hdl); From 872e8d26978a8e1caa1ca7d931db7f95d987a3e7 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 09:14:38 -0800 Subject: [PATCH 13/75] Add initial rw_uio functions to the dmu These functions were dropped originally because I felt they would need to be rewritten anyway to avoid using uios. However, this patch readds then with they dea they can just be reworked and the uio bits dropped. --- include/sys/dmu.h | 10 ++++- module/zfs/dmu.c | 112 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/include/sys/dmu.h b/include/sys/dmu.h index 575cb2d10..a8edfdbf8 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -515,12 +515,18 @@ void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_tx_t *tx); #ifdef _KERNEL int dmu_read_req(objset_t *os, uint64_t object, struct request *req); -int dmu_write_req(objset_t *os, uint64_t object, struct request *req, dmu_tx_t *tx); -#endif +int dmu_write_req(objset_t *os, uint64_t object, struct request *req, + dmu_tx_t *tx); +int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size); +int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size, + dmu_tx_t *tx); +int dmu_write_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size, + dmu_tx_t *tx); #ifdef HAVE_ZPL int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, struct page *pp, dmu_tx_t *tx); #endif +#endif struct arc_buf *dmu_request_arcbuf(dmu_buf_t *handle, int size); void dmu_return_arcbuf(struct arc_buf *buf); void dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, struct arc_buf *buf, diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index aaeec418d..79024e1ee 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -1122,9 +1122,113 @@ dmu_write_req(objset_t *os, uint64_t object, struct request *req, dmu_tx_t *tx) dmu_buf_rele_array(dbp, numbufs, FTAG); return (err); } -#endif -#ifdef HAVE_ZPL +int +dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size) +{ + dmu_buf_t **dbp; + int numbufs, i, err; + xuio_t *xuio = NULL; + + /* + * NB: we could do this block-at-a-time, but it's nice + * to be reading in parallel. + */ + err = dmu_buf_hold_array(os, object, uio->uio_loffset, size, TRUE, FTAG, + &numbufs, &dbp); + if (err) + return (err); + + for (i = 0; i < numbufs; i++) { + int tocpy; + int bufoff; + dmu_buf_t *db = dbp[i]; + + ASSERT(size > 0); + + bufoff = uio->uio_loffset - db->db_offset; + tocpy = (int)MIN(db->db_size - bufoff, size); + + if (xuio) { + dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db; + arc_buf_t *dbuf_abuf = dbi->db_buf; + arc_buf_t *abuf = dbuf_loan_arcbuf(dbi); + err = dmu_xuio_add(xuio, abuf, bufoff, tocpy); + if (!err) { + uio->uio_resid -= tocpy; + uio->uio_loffset += tocpy; + } + + if (abuf == dbuf_abuf) + XUIOSTAT_BUMP(xuiostat_rbuf_nocopy); + else + XUIOSTAT_BUMP(xuiostat_rbuf_copied); + } else { + err = uiomove((char *)db->db_data + bufoff, tocpy, + UIO_READ, uio); + } + if (err) + break; + + size -= tocpy; + } + dmu_buf_rele_array(dbp, numbufs, FTAG); + + return (err); +} + +static int +dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx) +{ + dmu_buf_t **dbp; + int numbufs; + int err = 0; + int i; + + err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size, + FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH); + if (err) + return (err); + + for (i = 0; i < numbufs; i++) { + int tocpy; + int bufoff; + dmu_buf_t *db = dbp[i]; + + ASSERT(size > 0); + + bufoff = uio->uio_loffset - db->db_offset; + tocpy = (int)MIN(db->db_size - bufoff, size); + + ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size); + + if (tocpy == db->db_size) + dmu_buf_will_fill(db, tx); + else + dmu_buf_will_dirty(db, tx); + + /* + * XXX uiomove could block forever (eg.nfs-backed + * pages). There needs to be a uiolockdown() function + * to lock the pages in memory, so that uiomove won't + * block. + */ + err = uiomove((char *)db->db_data + bufoff, tocpy, + UIO_WRITE, uio); + + if (tocpy == db->db_size) + dmu_buf_fill_done(db, tx); + + if (err) + break; + + size -= tocpy; + } + + dmu_buf_rele_array(dbp, numbufs, FTAG); + return (err); +} + int dmu_write_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size, dmu_tx_t *tx) @@ -1165,6 +1269,7 @@ dmu_write_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size, return (err); } +#ifdef HAVE_ZPL int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, page_t *pp, dmu_tx_t *tx) @@ -1219,7 +1324,8 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_rele_array(dbp, numbufs, FTAG); return (err); } -#endif +#endif /* HAVE_ZPL */ +#endif /* _KERNEL */ /* * Allocate a loaned anonymous arc buffer. From 72d5e2da3e45a6865806f1be908232f5fea8787b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 14:04:40 -0800 Subject: [PATCH 14/75] Add HAVE_SCANSTAMP This functionality is not supported under Linux, perhaps it will be some day if it's decided it's useful. --- module/zfs/zfs_sa.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c index 88fd78966..f4c599f88 100644 --- a/module/zfs/zfs_sa.c +++ b/module/zfs/zfs_sa.c @@ -67,7 +67,6 @@ sa_attr_reg_t zfs_attr_table[ZPL_END+1] = { }; #ifdef _KERNEL -#ifdef HAVE_ZPL int zfs_sa_readlink(znode_t *zp, uio_t *uio) { @@ -119,6 +118,7 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx) } } +#ifdef HAVE_SCANSTAMP void zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap) { @@ -183,6 +183,7 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) &zp->z_pflags, sizeof (uint64_t), tx)); } } +#endif /* HAVE_SCANSTAMP */ /* * I'm not convinced we should do any of this upgrade. @@ -205,7 +206,9 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) uint64_t uid, gid, mode, rdev, xattr, parent; uint64_t crtime[2], mtime[2], ctime[2]; zfs_acl_phys_t znode_acl; +#ifdef HAVE_SCANSTAMP char scanstamp[AV_SCANSTAMP_SZ]; +#endif /* HAVE_SCANSTAMP */ boolean_t drop_lock = B_FALSE; /* @@ -293,6 +296,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8); +#ifdef HAVE_SCANSTAMP /* if scanstamp then add scanstamp */ if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) { @@ -302,6 +306,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) NULL, scanstamp, AV_SCANSTAMP_SZ); zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP; } +#endif /* HAVE_SCANSTAMP */ VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0); VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs, @@ -331,5 +336,4 @@ zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp) } } -#endif /* HAVE_ZPL */ #endif From e5c39b95a7ccc19ce7a3af8d8d09f0b8959a3991 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 11:18:08 -0800 Subject: [PATCH 15/75] Export required vfs/vn symbols --- include/sys/Makefile.am | 1 + include/sys/Makefile.in | 3 ++ include/sys/zfs_vfsops.h | 8 ++++ include/sys/zfs_vnops.h | 80 ++++++++++++++++++++++++++++++++++++++++ module/zfs/zfs_vfsops.c | 32 +++++++++++----- module/zfs/zfs_vnops.c | 58 +++++++++++++++++++---------- 6 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 include/sys/zfs_vnops.h diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 59e137104..1aeb5da2d 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -62,6 +62,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/zfs_stat.h \ $(top_srcdir)/include/sys/zfs_vfsops.h \ $(top_srcdir)/include/sys/zfs_znode.h \ + $(top_srcdir)/include/sys/zfs_vnops.h \ $(top_srcdir)/include/sys/zil.h \ $(top_srcdir)/include/sys/zil_impl.h \ $(top_srcdir)/include/sys/zio_checksum.h \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 2e8af81de..59066479a 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -152,6 +152,7 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/zfs_stat.h \ $(top_srcdir)/include/sys/zfs_vfsops.h \ $(top_srcdir)/include/sys/zfs_znode.h \ + $(top_srcdir)/include/sys/zfs_vnops.h \ $(top_srcdir)/include/sys/zil.h \ $(top_srcdir)/include/sys/zil_impl.h \ $(top_srcdir)/include/sys/zio_checksum.h \ @@ -246,6 +247,7 @@ am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/zfs_stat.h \ $(top_srcdir)/include/sys/zfs_vfsops.h \ $(top_srcdir)/include/sys/zfs_znode.h \ + $(top_srcdir)/include/sys/zfs_vnops.h \ $(top_srcdir)/include/sys/zil.h \ $(top_srcdir)/include/sys/zil_impl.h \ $(top_srcdir)/include/sys/zio_checksum.h \ @@ -516,6 +518,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/zfs_stat.h \ $(top_srcdir)/include/sys/zfs_vfsops.h \ $(top_srcdir)/include/sys/zfs_znode.h \ + $(top_srcdir)/include/sys/zfs_vnops.h \ $(top_srcdir)/include/sys/zil.h \ $(top_srcdir)/include/sys/zil_impl.h \ $(top_srcdir)/include/sys/zio_checksum.h \ diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 38c87df43..ec4097768 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -152,6 +152,14 @@ extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp); extern void zfsvfs_free(zfsvfs_t *zfsvfs); extern int zfs_check_global_label(const char *dsname, const char *hexsl); +extern int zfs_register_callbacks(vfs_t *vfsp); +extern void zfs_unregister_callbacks(zfsvfs_t *zfsvfs); +extern int zfs_domount(vfs_t *vfsp, char *osname); +extern int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr); +extern int zfs_root(vfs_t *vfsp, vnode_t **vpp); +extern int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp); +extern int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp); + #ifdef __cplusplus } #endif diff --git a/include/sys/zfs_vnops.h b/include/sys/zfs_vnops.h new file mode 100644 index 000000000..64e2210de --- /dev/null +++ b/include/sys/zfs_vnops.h @@ -0,0 +1,80 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef _SYS_FS_ZFS_VNOPS_H +#define _SYS_FS_ZFS_VNOPS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, + caller_context_t *ct); +extern int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, + caller_context_t *ct); +extern int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, + struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr, + caller_context_t *ct, int *direntflags, pathname_t *realpnp); +extern int zfs_create(vnode_t *dvp, char *name, vattr_t *vap, + int excl, int mode, vnode_t **vpp, cred_t *cr, int flag, + caller_context_t *ct, vsecattr_t *vsecp); +extern int zfs_remove(vnode_t *dvp, char *name, cred_t *cr, + caller_context_t *ct, int flags); +extern int zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, + vnode_t **vpp, cred_t *cr, caller_context_t *ct, int flags, + vsecattr_t *vsecp); +extern int zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, + caller_context_t *ct, int flags); +extern int zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, + caller_context_t *ct); +extern int zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, + caller_context_t *ct); +extern int zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, + caller_context_t *ct); +extern int zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, + cred_t *cr, caller_context_t *ct, int flags); +extern int zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, + cred_t *cr, caller_context_t *ct, int flags); +extern int zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, + caller_context_t *ct); +extern int zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, + caller_context_t *ct, int flags); +extern void zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct); +extern int zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, + offset_t offset, cred_t *cr, caller_context_t *ct); +extern int zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct); +extern int zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, + cred_t *cr, caller_context_t *ct); +extern int zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, + cred_t *cr, caller_context_t *ct); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_FS_ZFS_VNOPS_H */ diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 30bbcccb4..4e571ed6d 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -75,11 +75,7 @@ static kmutex_t zfs_dev_mtx; extern int sys_shutdown; static int zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr); -static int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr); static int zfs_mountroot(vfs_t *vfsp, enum whymountroot); -static int zfs_root(vfs_t *vfsp, vnode_t **vpp); -static int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp); -static int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp); static void zfs_freevfs(vfs_t *vfsp); static const fs_operation_def_t zfs_vfsops_template[] = { @@ -181,6 +177,7 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) return (0); } +EXPORT_SYMBOL(zfs_sync); static int zfs_create_unique_device(dev_t *dev) @@ -392,7 +389,7 @@ acl_inherit_changed_cb(void *arg, uint64_t newval) zfsvfs->z_acl_inherit = newval; } -static int +int zfs_register_callbacks(vfs_t *vfsp) { struct dsl_dataset *ds = NULL; @@ -561,6 +558,7 @@ unregister: return (error); } +EXPORT_SYMBOL(zfs_register_callbacks); #endif /* HAVE_ZPL */ static int @@ -689,6 +687,7 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, zap_cursor_fini(&zc); return (error); } +EXPORT_SYMBOL(zfs_userspace_many); /* * buf must be big enough (eg, 32 bytes) @@ -736,6 +735,7 @@ zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, err = 0; return (err); } +EXPORT_SYMBOL(zfs_userspace_one); int zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, @@ -797,6 +797,7 @@ zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, dmu_tx_commit(tx); return (err); } +EXPORT_SYMBOL(zfs_set_userquota); boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid) @@ -821,6 +822,7 @@ zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid) return (B_FALSE); return (used >= quota); } +EXPORT_SYMBOL(zfs_fuid_overquota); boolean_t zfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup) @@ -837,6 +839,7 @@ zfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup) return (zfs_fuid_overquota(zfsvfs, isgroup, fuid)); } +EXPORT_SYMBOL(zfs_owner_overquota); int zfsvfs_create(const char *osname, zfsvfs_t **zfvp) @@ -1102,7 +1105,7 @@ zfs_set_fuid_feature(zfsvfs_t *zfsvfs) zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); } -static int +int zfs_domount(vfs_t *vfsp, char *osname) { dev_t mount_dev; @@ -1196,6 +1199,7 @@ out: return (error); } +EXPORT_SYMBOL(zfs_domount); void zfs_unregister_callbacks(zfsvfs_t *zfsvfs) @@ -1239,6 +1243,7 @@ zfs_unregister_callbacks(zfsvfs_t *zfsvfs) vscan_changed_cb, zfsvfs) == 0); } } +EXPORT_SYMBOL(zfs_unregister_callbacks); /* * Convert a decimal digit string to a uint64_t integer. @@ -1643,7 +1648,7 @@ out: return (error); } -static int +int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; @@ -1706,8 +1711,9 @@ zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_statvfs); -static int +int zfs_root(vfs_t *vfsp, vnode_t **vpp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; @@ -1723,6 +1729,7 @@ zfs_root(vfs_t *vfsp, vnode_t **vpp) ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_root); /* * Teardown the zfsvfs::z_os. @@ -1821,7 +1828,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) } /*ARGSUSED*/ -static int +int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr) { zfsvfs_t *zfsvfs = vfsp->vfs_data; @@ -1904,8 +1911,9 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr) return (0); } +EXPORT_SYMBOL(zfs_umount); -static int +int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; @@ -1990,6 +1998,7 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_vget); /* * Block out VOPs and close zfsvfs_t::z_os @@ -2008,6 +2017,7 @@ zfs_suspend_fs(zfsvfs_t *zfsvfs) return (0); } +EXPORT_SYMBOL(zfs_suspend_fs); /* * Reopen zfsvfs_t::z_os and release VOPs. @@ -2071,6 +2081,7 @@ bail: } return (err); } +EXPORT_SYMBOL(zfs_resume_fs); static void zfs_freevfs(vfs_t *vfsp) @@ -2229,6 +2240,7 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) return (0); } +EXPORT_SYMBOL(zfs_set_version); #endif /* HAVE_ZPL */ /* diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 44bae8e34..b666ee39c 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -443,7 +444,7 @@ offset_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */ * vp - atime updated if byte count > 0 */ /* ARGSUSED */ -static int +int zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(vp); @@ -566,6 +567,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_read); /* * Write the bytes to a file. @@ -587,7 +589,7 @@ out: */ /* ARGSUSED */ -static int +int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(vp); @@ -939,6 +941,7 @@ again: ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_write); void zfs_get_done(zgd_t *zgd, int error) @@ -1152,7 +1155,7 @@ specvp_check(vnode_t **vpp, cred_t *cr) * NA */ /* ARGSUSED */ -static int +int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, int *direntflags, pathname_t *realpnp) @@ -1269,6 +1272,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_lookup); /* * Attempt to create a new entry in a directory. If the entry @@ -1296,8 +1300,8 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, */ /* ARGSUSED */ -static int -zfs_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl, +int +zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct, vsecattr_t *vsecp) { @@ -1529,6 +1533,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_create); /* * Remove an entry from a directory. @@ -1550,7 +1555,7 @@ out: uint64_t null_xattr = 0; /*ARGSUSED*/ -static int +int zfs_remove(vnode_t *dvp, char *name, cred_t *cr, caller_context_t *ct, int flags) { @@ -1760,6 +1765,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_remove); /* * Create a new directory and insert it into dvp using the name @@ -1782,7 +1788,7 @@ out: * vp - ctime|mtime|atime updated */ /*ARGSUSED*/ -static int +int zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, caller_context_t *ct, int flags, vsecattr_t *vsecp) { @@ -1942,6 +1948,7 @@ top: ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_mkdir); /* * Remove a directory subdir entry. If the current working @@ -1962,7 +1969,7 @@ top: * dvp - ctime|mtime updated */ /*ARGSUSED*/ -static int +int zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, caller_context_t *ct, int flags) { @@ -2070,6 +2077,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_rmdir); /* * Read as many directory entries as will fit into the provided @@ -2364,7 +2372,7 @@ update: ulong_t zfs_fsync_sync_cnt = 4; -static int +int zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(vp); @@ -2390,6 +2398,7 @@ zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) } return (0); } +EXPORT_SYMBOL(zfs_fsync); /* @@ -2408,7 +2417,7 @@ zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) * RETURN: 0 (always succeeds) */ /* ARGSUSED */ -static int +int zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, caller_context_t *ct) { @@ -2594,6 +2603,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_getattr); /* * Set the file attributes to the values contained in the @@ -2614,7 +2624,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, * vp - ctime updated, mtime updated if size changed. */ /* ARGSUSED */ -static int +int zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, caller_context_t *ct) { @@ -3226,6 +3236,7 @@ out2: ZFS_EXIT(zfsvfs); return (err); } +EXPORT_SYMBOL(zfs_setattr); typedef struct zfs_zlock { krwlock_t *zl_rwlock; /* lock we acquired */ @@ -3343,7 +3354,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) * sdvp,tdvp - ctime|mtime updated */ /*ARGSUSED*/ -static int +int zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr, caller_context_t *ct, int flags) { @@ -3677,6 +3688,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_rename); /* * Insert the indicated symbolic reference entry into the directory. @@ -3696,7 +3708,7 @@ out: * dvp - ctime|mtime updated */ /*ARGSUSED*/ -static int +int zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, cred_t *cr, caller_context_t *ct, int flags) { @@ -3830,6 +3842,7 @@ top: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_symlink); /* * Return, in the buffer contained in the provided uio structure, @@ -3849,7 +3862,7 @@ top: * vp - atime updated */ /* ARGSUSED */ -static int +int zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(vp); @@ -3872,6 +3885,7 @@ zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct) ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_readlink); /* * Insert a new entry into directory tdvp referencing svp. @@ -3890,7 +3904,7 @@ zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct) * svp - ctime updated */ /* ARGSUSED */ -static int +int zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, caller_context_t *ct, int flags) { @@ -4026,6 +4040,7 @@ top: ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_link); /* * zfs_null_putapage() is used when the file system has been force @@ -4323,6 +4338,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) zfs_zinactive(zp); rw_exit(&zfsvfs->z_teardown_inactive_lock); } +EXPORT_SYMBOL(zfs_inactive); /* * Bounds-check the seek operation. @@ -4711,7 +4727,7 @@ zfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, * vp - ctime|mtime updated */ /* ARGSUSED */ -static int +int zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, offset_t offset, cred_t *cr, caller_context_t *ct) { @@ -4746,9 +4762,10 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_space); /*ARGSUSED*/ -static int +int zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) { znode_t *zp = VTOZ(vp); @@ -4807,6 +4824,7 @@ zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) ZFS_EXIT(zfsvfs); return (0); } +EXPORT_SYMBOL(zfs_fid); static int zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, @@ -4879,7 +4897,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, } /*ARGSUSED*/ -static int +int zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, caller_context_t *ct) { @@ -4895,9 +4913,10 @@ zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, return (error); } +EXPORT_SYMBOL(zfs_getsecattr); /*ARGSUSED*/ -static int +int zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, caller_context_t *ct) { @@ -4918,6 +4937,7 @@ zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_setsecattr); /* * Tunable, both must be a power of 2. From 1ee1b76786aebc6eed546c6e869cc88f1e318890 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 14:21:46 -0800 Subject: [PATCH 16/75] Conserve stack in zfs_sa_upgrade() As always under Linux stack space is at a premium. Relocate two 20 element sa_bulk_attr_t arrays in zfs_sa_upgrade() from the stack to the heap. --- module/zfs/zfs_sa.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c index f4c599f88..68bce0a6e 100644 --- a/module/zfs/zfs_sa.c +++ b/module/zfs/zfs_sa.c @@ -199,9 +199,8 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) dmu_buf_t *db = sa_get_db(hdl); znode_t *zp = sa_get_userdata(hdl); zfsvfs_t *zfsvfs = zp->z_zfsvfs; - sa_bulk_attr_t bulk[20]; int count = 0; - sa_bulk_attr_t sa_attrs[20] = { 0 }; + sa_bulk_attr_t *bulk, *sa_attrs; zfs_acl_locator_cb_t locate = { 0 }; uint64_t uid, gid, mode, rdev, xattr, parent; uint64_t crtime[2], mtime[2], ctime[2]; @@ -237,6 +236,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) } /* First do a bulk query of the attributes that aren't cached */ + bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16); @@ -249,15 +249,17 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, &znode_acl, 88); - if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) + if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) { + kmem_free(bulk, sizeof(sa_bulk_attr_t) * 20); goto done; - + } /* * While the order here doesn't matter its best to try and organize * it is such a way to pick up an already existing layout number */ count = 0; + sa_attrs = kmem_zalloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zfsvfs), NULL, &zp->z_size, 8); @@ -316,6 +318,8 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) znode_acl.z_acl_extern_obj, tx)); zp->z_is_sa = B_TRUE; + kmem_free(sa_attrs, sizeof(sa_bulk_attr_t) * 20); + kmem_free(bulk, sizeof(sa_bulk_attr_t) * 20); done: if (drop_lock) mutex_exit(&zp->z_lock); From f30484afc32b6040a15fabfc697cfb76116e468f Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 7 Jan 2011 13:47:47 -0800 Subject: [PATCH 17/75] Conserve stack in zfs_mkdir() Move the sa_attrs array from the stack to the heap to minimize stack space usage. --- module/zfs/zfs_znode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 93f2f026e..b7f95f4f0 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -773,7 +773,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, int bonuslen; sa_handle_t *sa_hdl; dmu_object_type_t obj_type; - sa_bulk_attr_t sa_attrs[ZPL_END]; + sa_bulk_attr_t *sa_attrs; int cnt = 0; zfs_acl_locator_cb_t locate = { 0 }; @@ -899,6 +899,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, * order for DMU_OT_ZNODE is critical since it needs to be constructed * in the old znode_phys_t format. Don't change this ordering */ + sa_attrs = kmem_alloc(sizeof(sa_bulk_attr_t) * ZPL_END, KM_SLEEP); if (obj_type == DMU_OT_ZNODE) { SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zfsvfs), @@ -1002,6 +1003,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, err = zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx); ASSERT3S(err, ==, 0); } + kmem_free(sa_attrs, sizeof(sa_bulk_attr_t) * ZPL_END); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); } From 5649246dd3ba02041c83f7bab1c19c5815f9b771 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 7 Jan 2011 12:40:30 -0800 Subject: [PATCH 18/75] Remove znode move functionality Unlike Solaris the Linux implementation embeds the inode in the znode, and has no use for a vnode. So while it's true that fragmention of the znode cache may occur it should not be worse than any of the other Linux FS inode caches. Until proven that this is a problem it's just added complexity we don't need. --- module/zfs/zfs_znode.c | 184 ----------------------------------------- 1 file changed, 184 deletions(-) diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index b7f95f4f0..908ac6d49 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -160,189 +160,6 @@ zfs_znode_cache_destructor(void *buf, void *arg) ASSERT(zp->z_acl_cached == NULL); } -#ifdef ZNODE_STATS -static struct { - uint64_t zms_zfsvfs_invalid; - uint64_t zms_zfsvfs_recheck1; - uint64_t zms_zfsvfs_unmounted; - uint64_t zms_zfsvfs_recheck2; - uint64_t zms_obj_held; - uint64_t zms_vnode_locked; - uint64_t zms_not_only_dnlc; -} znode_move_stats; -#endif /* ZNODE_STATS */ - -static void -zfs_znode_move_impl(znode_t *ozp, znode_t *nzp) -{ - vnode_t *vp; - - /* Copy fields. */ - nzp->z_zfsvfs = ozp->z_zfsvfs; - - /* Swap vnodes. */ - vp = nzp->z_vnode; - nzp->z_vnode = ozp->z_vnode; - ozp->z_vnode = vp; /* let destructor free the overwritten vnode */ - ZTOV(ozp)->v_data = ozp; - ZTOV(nzp)->v_data = nzp; - - nzp->z_id = ozp->z_id; - ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */ - ASSERT(avl_numnodes(&ozp->z_range_avl) == 0); - nzp->z_unlinked = ozp->z_unlinked; - nzp->z_atime_dirty = ozp->z_atime_dirty; - nzp->z_zn_prefetch = ozp->z_zn_prefetch; - nzp->z_blksz = ozp->z_blksz; - nzp->z_seq = ozp->z_seq; - nzp->z_mapcnt = ozp->z_mapcnt; - nzp->z_gen = ozp->z_gen; - nzp->z_sync_cnt = ozp->z_sync_cnt; - nzp->z_is_sa = ozp->z_is_sa; - nzp->z_sa_hdl = ozp->z_sa_hdl; - bcopy(ozp->z_atime, nzp->z_atime, sizeof (uint64_t) * 2); - nzp->z_links = ozp->z_links; - nzp->z_size = ozp->z_size; - nzp->z_pflags = ozp->z_pflags; - nzp->z_uid = ozp->z_uid; - nzp->z_gid = ozp->z_gid; - nzp->z_mode = ozp->z_mode; - - /* - * Since this is just an idle znode and kmem is already dealing with - * memory pressure, release any cached ACL. - */ - if (ozp->z_acl_cached) { - zfs_acl_free(ozp->z_acl_cached); - ozp->z_acl_cached = NULL; - } - - sa_set_userp(nzp->z_sa_hdl, nzp); - - /* - * Invalidate the original znode by clearing fields that provide a - * pointer back to the znode. Set the low bit of the vfs pointer to - * ensure that zfs_znode_move() recognizes the znode as invalid in any - * subsequent callback. - */ - ozp->z_sa_hdl = NULL; - POINTER_INVALIDATE(&ozp->z_zfsvfs); - - /* - * Mark the znode. - */ - nzp->z_moved = 1; - ozp->z_moved = (uint8_t)-1; -} - -/*ARGSUSED*/ -static kmem_cbrc_t -zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg) -{ - znode_t *ozp = buf, *nzp = newbuf; - zfsvfs_t *zfsvfs; - vnode_t *vp; - - /* - * The znode is on the file system's list of known znodes if the vfs - * pointer is valid. We set the low bit of the vfs pointer when freeing - * the znode to invalidate it, and the memory patterns written by kmem - * (baddcafe and deadbeef) set at least one of the two low bits. A newly - * created znode sets the vfs pointer last of all to indicate that the - * znode is known and in a valid state to be moved by this function. - */ - zfsvfs = ozp->z_zfsvfs; - if (!POINTER_IS_VALID(zfsvfs)) { - ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_invalid); - return (KMEM_CBRC_DONT_KNOW); - } - - /* - * Close a small window in which it's possible that the filesystem could - * be unmounted and freed, and zfsvfs, though valid in the previous - * statement, could point to unrelated memory by the time we try to - * prevent the filesystem from being unmounted. - */ - rw_enter(&zfsvfs_lock, RW_WRITER); - if (zfsvfs != ozp->z_zfsvfs) { - rw_exit(&zfsvfs_lock); - ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck1); - return (KMEM_CBRC_DONT_KNOW); - } - - /* - * If the znode is still valid, then so is the file system. We know that - * no valid file system can be freed while we hold zfsvfs_lock, so we - * can safely ensure that the filesystem is not and will not be - * unmounted. The next statement is equivalent to ZFS_ENTER(). - */ - rrw_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG); - if (zfsvfs->z_unmounted) { - ZFS_EXIT(zfsvfs); - rw_exit(&zfsvfs_lock); - ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted); - return (KMEM_CBRC_DONT_KNOW); - } - rw_exit(&zfsvfs_lock); - - mutex_enter(&zfsvfs->z_znodes_lock); - /* - * Recheck the vfs pointer in case the znode was removed just before - * acquiring the lock. - */ - if (zfsvfs != ozp->z_zfsvfs) { - mutex_exit(&zfsvfs->z_znodes_lock); - ZFS_EXIT(zfsvfs); - ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck2); - return (KMEM_CBRC_DONT_KNOW); - } - - /* - * At this point we know that as long as we hold z_znodes_lock, the - * znode cannot be freed and fields within the znode can be safely - * accessed. Now, prevent a race with zfs_zget(). - */ - if (ZFS_OBJ_HOLD_TRYENTER(zfsvfs, ozp->z_id) == 0) { - mutex_exit(&zfsvfs->z_znodes_lock); - ZFS_EXIT(zfsvfs); - ZNODE_STAT_ADD(znode_move_stats.zms_obj_held); - return (KMEM_CBRC_LATER); - } - - vp = ZTOV(ozp); - if (mutex_tryenter(&vp->v_lock) == 0) { - ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); - mutex_exit(&zfsvfs->z_znodes_lock); - ZFS_EXIT(zfsvfs); - ZNODE_STAT_ADD(znode_move_stats.zms_vnode_locked); - return (KMEM_CBRC_LATER); - } - - /* Only move znodes that are referenced _only_ by the DNLC. */ - if (vp->v_count != 1 || !vn_in_dnlc(vp)) { - mutex_exit(&vp->v_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); - mutex_exit(&zfsvfs->z_znodes_lock); - ZFS_EXIT(zfsvfs); - ZNODE_STAT_ADD(znode_move_stats.zms_not_only_dnlc); - return (KMEM_CBRC_LATER); - } - - /* - * The znode is known and in a valid state to move. We're holding the - * locks needed to execute the critical section. - */ - zfs_znode_move_impl(ozp, nzp); - mutex_exit(&vp->v_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); - - list_link_replace(&ozp->z_link_node, &nzp->z_link_node); - mutex_exit(&zfsvfs->z_znodes_lock); - ZFS_EXIT(zfsvfs); - - return (KMEM_CBRC_YES); -} - void zfs_znode_init(void) { @@ -354,7 +171,6 @@ zfs_znode_init(void) znode_cache = kmem_cache_create("zfs_znode_cache", sizeof (znode_t), 0, zfs_znode_cache_constructor, zfs_znode_cache_destructor, NULL, NULL, NULL, 0); - kmem_cache_set_move(znode_cache, zfs_znode_move); } void From bc3e15e386a62c29e10194e5fae3c4f8a76337df Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 16:47:31 -0800 Subject: [PATCH 19/75] Wrap with HAVE_MLSLABEL The zfs_check_global_label() function is part of the HAVE_MLSLABEL support which was previously commented out by a HAVE_ZPL check. Since we're still deciding what to do about mls labels wrap it with the preexisting macro to keep it compiled out. --- module/zfs/zfs_vfsops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 4e571ed6d..a97d0bdb7 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1300,6 +1300,7 @@ zfs_parse_bootfs(char *bpath, char *outpath) return (error); } +#ifdef HAVE_MLSLABEL /* * zfs_check_global_label: * Check that the hex label string is appropriate for the dataset @@ -1327,6 +1328,7 @@ zfs_check_global_label(const char *dsname, const char *hexsl) } return (EACCES); } +#endif /* HAVE_MLSLABEL */ /* * zfs_mount_label_policy: From 9ee7fac5312f9c6b33155aed77e50b0dfd68a77d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 7 Jan 2011 11:51:27 -0800 Subject: [PATCH 20/75] VFS: Wrap with HAVE_SHARE Certain NFS/SMB share functionality is not yet in place. These functions used to be wrapped with the generic HAVE_ZPL to prevent them from being compiled. I still don't want them compiled but I'm working toward eliminating the use of HAVE_ZPL. So I'm just renaming the wrapper here to HAVE_SHARE. They still won't be compiled until all the share issues are worked through. Share support is the last missing piece from zfs_ioctl.c. --- module/zfs/zfs_ioctl.c | 36 ++++++++++++++++++------------------ module/zfs/zfs_znode.c | 4 ++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 6e8422bb0..17f3ff60b 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -592,7 +592,7 @@ zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr) return (error); } -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE static int zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr) { @@ -616,12 +616,12 @@ zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr) return (dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_SHARE, cr)); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ int zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) { -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE if (!INGLOBALZONE(curproc)) return (EPERM); @@ -632,13 +632,13 @@ zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) } #else return (ENOTSUP); -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ } int zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr) { -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE if (!INGLOBALZONE(curproc)) return (EPERM); @@ -649,7 +649,7 @@ zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr) } #else return (ENOTSUP); -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ } static int @@ -4205,7 +4205,7 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) * the first file system is shared. * Neither sharefs, nfs or smbsrv are unloadable modules. */ -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE int (*znfsexport_fs)(void *arg); int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t); int (*zsmbexport_fs)(void *arg, boolean_t add_share); @@ -4237,12 +4237,12 @@ zfs_init_sharefs() } return (0); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ static int zfs_ioc_share(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE int error; int opcode; @@ -4334,7 +4334,7 @@ zfs_ioc_share(zfs_cmd_t *zc) return (error); #else return (ENOTSUP); -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ } ace_t full_access[] = { @@ -4451,7 +4451,7 @@ zfs_ioc_diff(zfs_cmd_t *zc) /* * Remove all ACL files in shares dir */ -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE static int zfs_smb_acl_purge(znode_t *dzp) { @@ -4470,12 +4470,12 @@ zfs_smb_acl_purge(znode_t *dzp) zap_cursor_fini(&zc); return (error); } -#endif /* HAVE ZPL */ +#endif /* HAVE SHARE */ static int zfs_ioc_smb_acl(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE vnode_t *vp; znode_t *dzp; vnode_t *resourcevp = NULL; @@ -4600,7 +4600,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) return (error); #else return (ENOTSUP); -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ } /* @@ -5221,12 +5221,12 @@ _init(void) if ((error = zfs_attach()) != 0) goto out2; -#ifdef HAVE_ZPL tsd_create(&zfs_fsyncer_key, NULL); tsd_create(&rrw_tsd_key, NULL); +#ifdef HAVE_SHARE mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); -#endif /* HAVE_ZPL */ +#endif /* HAVE_SHARE */ printk(KERN_NOTICE "ZFS: Loaded ZFS Filesystem v%s%s\n", ZFS_META_VERSION, ZFS_DEBUG_STR); @@ -5251,7 +5251,7 @@ _fini(void) zvol_fini(); zfs_fini(); spa_fini(); -#ifdef HAVE_ZPL +#ifdef HAVE_SHARE if (zfs_nfsshare_inited) (void) ddi_modclose(nfs_mod); if (zfs_smbshare_inited) @@ -5260,8 +5260,8 @@ _fini(void) (void) ddi_modclose(sharefs_mod); mutex_destroy(&zfs_share_lock); +#endif /* HAVE_SHARE */ tsd_destroy(&zfs_fsyncer_key); -#endif /* HAVE_ZPL */ printk(KERN_NOTICE "ZFS: Unloaded ZFS Filesystem v%s%s\n", ZFS_META_VERSION, ZFS_DEBUG_STR); diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 908ac6d49..137a06810 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -285,6 +285,7 @@ zfs_create_op_tables() int zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) { +#ifdef HAVE_SHARE zfs_acl_ids_t acl_ids; vattr_t vattr; znode_t *sharezp; @@ -326,6 +327,9 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) kmem_cache_free(znode_cache, sharezp); return (error); +#else + return (0); +#endif /* HAVE_SHARE */ } /* From 4e1b54fdde35e952ea7084a4640e08c6e42f8a94 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 16:49:45 -0800 Subject: [PATCH 21/75] Remove zfs_parse_bootfs() support Remove unneeded bootfs functions. This support shouldn't be required for the Linux port, and even if it is it would need to be reworked to integrate cleanly with Linux. --- module/zfs/zfs_vfsops.c | 55 ----------------------------------------- 1 file changed, 55 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index a97d0bdb7..ef433125a 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1245,61 +1245,6 @@ zfs_unregister_callbacks(zfsvfs_t *zfsvfs) } EXPORT_SYMBOL(zfs_unregister_callbacks); -/* - * Convert a decimal digit string to a uint64_t integer. - */ -static int -str_to_uint64(char *str, uint64_t *objnum) -{ - uint64_t num = 0; - - while (*str) { - if (*str < '0' || *str > '9') - return (EINVAL); - - num = num*10 + *str++ - '0'; - } - - *objnum = num; - return (0); -} - -/* - * The boot path passed from the boot loader is in the form of - * "rootpool-name/root-filesystem-object-number'. Convert this - * string to a dataset name: "rootpool-name/root-filesystem-name". - */ -static int -zfs_parse_bootfs(char *bpath, char *outpath) -{ - char *slashp; - uint64_t objnum; - int error; - - if (*bpath == 0 || *bpath == '/') - return (EINVAL); - - (void) strcpy(outpath, bpath); - - slashp = strchr(bpath, '/'); - - /* if no '/', just return the pool name */ - if (slashp == NULL) { - return (0); - } - - /* if not a number, just return the root dataset name */ - if (str_to_uint64(slashp+1, &objnum)) { - return (0); - } - - *slashp = '\0'; - error = dsl_dsobj_to_dsname(bpath, objnum, outpath); - *slashp = '/'; - - return (error); -} - #ifdef HAVE_MLSLABEL /* * zfs_check_global_label: From c60bc1fbf0760c9797411e10c05426fc41052f0a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 21 Dec 2010 14:38:27 -0800 Subject: [PATCH 22/75] Remove dead ACL code The following code was unused which caused gcc to complain. Since it was deadcode it has simply been removed. --- module/zfs/zfs_acl.c | 76 +------------------------------------------- 1 file changed, 1 insertion(+), 75 deletions(-) diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index 3efd4f88e..9263ceeb4 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -644,13 +644,6 @@ zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt, return ((uint64_t)(uintptr_t)acep); } -static zfs_acl_node_t * -zfs_acl_curr_node(zfs_acl_t *aclp) -{ - ASSERT(aclp->z_curr_node); - return (aclp->z_curr_node); -} - /* * Copy ACE to internal ZFS format. * While processing the ACL each ACE will be validated for correctness. @@ -1332,73 +1325,6 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) return (sa_bulk_update(zp->z_sa_hdl, bulk, count, tx)); } -/* - * Update access mask for prepended ACE - * - * This applies the "groupmask" value for aclmode property. - */ -static void -zfs_acl_prepend_fixup(zfs_acl_t *aclp, void *acep, void *origacep, - mode_t mode, uint64_t owner) -{ - int rmask, wmask, xmask; - int user_ace; - uint16_t aceflags; - uint32_t origmask, acepmask; - uint64_t fuid; - - aceflags = aclp->z_ops.ace_flags_get(acep); - fuid = aclp->z_ops.ace_who_get(acep); - origmask = aclp->z_ops.ace_mask_get(origacep); - acepmask = aclp->z_ops.ace_mask_get(acep); - - user_ace = (!(aceflags & - (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP))); - - if (user_ace && (fuid == owner)) { - rmask = S_IRUSR; - wmask = S_IWUSR; - xmask = S_IXUSR; - } else { - rmask = S_IRGRP; - wmask = S_IWGRP; - xmask = S_IXGRP; - } - - if (origmask & ACE_READ_DATA) { - if (mode & rmask) { - acepmask &= ~ACE_READ_DATA; - } else { - acepmask |= ACE_READ_DATA; - } - } - - if (origmask & ACE_WRITE_DATA) { - if (mode & wmask) { - acepmask &= ~ACE_WRITE_DATA; - } else { - acepmask |= ACE_WRITE_DATA; - } - } - - if (origmask & ACE_APPEND_DATA) { - if (mode & wmask) { - acepmask &= ~ACE_APPEND_DATA; - } else { - acepmask |= ACE_APPEND_DATA; - } - } - - if (origmask & ACE_EXECUTE) { - if (mode & xmask) { - acepmask &= ~ACE_EXECUTE; - } else { - acepmask |= ACE_EXECUTE; - } - } - aclp->z_ops.ace_mask_set(acep, acepmask); -} - static void zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp) { @@ -2072,7 +1998,7 @@ top: if (fuidp) zfs_fuid_info_free(fuidp); dmu_tx_commit(tx); -done: + mutex_exit(&zp->z_lock); mutex_exit(&zp->z_acl_lock); From 538f669f63e43b1d2a288c872a66b9d18b4a4bee Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 12 Jan 2011 12:51:48 -0800 Subject: [PATCH 23/75] Add trivial acl helpers The zfs acl code makes use of the two OpenSolaris helper functions acl_trivial_access_masks() and ace_trivial_common(). Since they are only called from zfs_acl.c I've brought them over from OpenSolaris and added them as static function to this file. This way I don't need to reimplement this functionality from scratch in the SPL. Long term once I take a more careful look at the acl implementation it may be the case that these functions really aren't needed. If that turns out to be the case they can then be removed. --- module/zfs/zfs_acl.c | 121 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index 9263ceeb4..ea209ba52 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -53,7 +53,6 @@ #include #include #include "fs/fs_subr.h" -#include #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE #define DENY ACE_ACCESS_DENIED_ACE_TYPE @@ -1166,6 +1165,126 @@ zfs_acl_chown_setattr(znode_t *zp) return (error); } +static void +acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1, + uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone) +{ + *deny1 = *deny2 = *allow0 = *group = 0; + + if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) + *deny1 |= ACE_READ_DATA; + if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) + *deny1 |= ACE_WRITE_DATA; + if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))) + *deny1 |= ACE_EXECUTE; + + if (!(mode & S_IRGRP) && (mode & S_IROTH)) + *deny2 = ACE_READ_DATA; + if (!(mode & S_IWGRP) && (mode & S_IWOTH)) + *deny2 |= ACE_WRITE_DATA; + if (!(mode & S_IXGRP) && (mode & S_IXOTH)) + *deny2 |= ACE_EXECUTE; + + if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH))) + *allow0 |= ACE_READ_DATA; + if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH))) + *allow0 |= ACE_WRITE_DATA; + if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH))) + *allow0 |= ACE_EXECUTE; + + *owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL| + ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES| + ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE; + if (mode & S_IRUSR) + *owner |= ACE_READ_DATA; + if (mode & S_IWUSR) + *owner |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXUSR) + *owner |= ACE_EXECUTE; + + *group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS| + ACE_SYNCHRONIZE; + if (mode & S_IRGRP) + *group |= ACE_READ_DATA; + if (mode & S_IWGRP) + *group |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXGRP) + *group |= ACE_EXECUTE; + + *everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS| + ACE_SYNCHRONIZE; + if (mode & S_IROTH) + *everyone |= ACE_READ_DATA; + if (mode & S_IWOTH) + *everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXOTH) + *everyone |= ACE_EXECUTE; +} + +/* + * ace_trivial: + * determine whether an ace_t acl is trivial + * + * Trivialness implies that the acl is composed of only + * owner, group, everyone entries. ACL can't + * have read_acl denied, and write_owner/write_acl/write_attributes + * can only be owner@ entry. + */ +static int +ace_trivial_common(void *acep, int aclcnt, + uint64_t (*walk)(void *, uint64_t, int aclcnt, + uint16_t *, uint16_t *, uint32_t *)) +{ + uint16_t flags; + uint32_t mask; + uint16_t type; + uint64_t cookie = 0; + + while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) { + switch (flags & ACE_TYPE_FLAGS) { + case ACE_OWNER: + case ACE_GROUP|ACE_IDENTIFIER_GROUP: + case ACE_EVERYONE: + break; + default: + return (1); + } + + if (flags & (ACE_FILE_INHERIT_ACE| + ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE| + ACE_INHERIT_ONLY_ACE)) + return (1); + + /* + * Special check for some special bits + * + * Don't allow anybody to deny reading basic + * attributes or a files ACL. + */ + if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) && + (type == ACE_ACCESS_DENIED_ACE_TYPE)) + return (1); + + /* + * Delete permissions are never set by default + */ + if (mask & (ACE_DELETE|ACE_DELETE_CHILD)) + return (1); + /* + * only allow owner@ to have + * write_acl/write_owner/write_attributes/write_xattr/ + */ + if (type == ACE_ACCESS_ALLOWED_ACE_TYPE && + (!(flags & ACE_OWNER) && (mask & + (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES| + ACE_WRITE_NAMED_ATTRS)))) + return (1); + + } + + return (0); +} + /* * common code for setting ACLs. * From 590329b50cda53cad87a4222d55cdbb35bfcf494 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 22 Dec 2010 12:13:57 -0800 Subject: [PATCH 24/75] Add basic uio support This code originates in OpenSolaris and was modified by KQ Infotech to be compatible with Linux. While supporting uios in the short term is useful to get something working this is not an abstraction we want to keep. This code is expected to be short lived and removed as soon as all the remaining uio based APIs and updated. --- include/sys/Makefile.am | 1 + include/sys/Makefile.in | 3 + include/sys/uio_impl.h | 49 +++++++ include/sys/zfs_context.h | 3 +- lib/libzpool/Makefile.am | 1 + lib/libzpool/Makefile.in | 18 ++- module/zcommon/Makefile.in | 1 + module/zcommon/zfs_uio.c | 255 +++++++++++++++++++++++++++++++++++++ 8 files changed, 325 insertions(+), 6 deletions(-) create mode 100644 include/sys/uio_impl.h create mode 100644 module/zcommon/zfs_uio.c diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 1aeb5da2d..a2e8dd01b 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -42,6 +42,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/u8_textprep.h \ $(top_srcdir)/include/sys/uberblock.h \ $(top_srcdir)/include/sys/uberblock_impl.h \ + $(top_srcdir)/include/sys/uio_impl.h \ $(top_srcdir)/include/sys/unique.h \ $(top_srcdir)/include/sys/uuid.h \ $(top_srcdir)/include/sys/vdev_disk.h \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 59066479a..4ab3927b0 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -132,6 +132,7 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/u8_textprep.h \ $(top_srcdir)/include/sys/uberblock.h \ $(top_srcdir)/include/sys/uberblock_impl.h \ + $(top_srcdir)/include/sys/uio_impl.h \ $(top_srcdir)/include/sys/unique.h \ $(top_srcdir)/include/sys/uuid.h \ $(top_srcdir)/include/sys/vdev_disk.h \ @@ -227,6 +228,7 @@ am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/u8_textprep.h \ $(top_srcdir)/include/sys/uberblock.h \ $(top_srcdir)/include/sys/uberblock_impl.h \ + $(top_srcdir)/include/sys/uio_impl.h \ $(top_srcdir)/include/sys/unique.h \ $(top_srcdir)/include/sys/uuid.h \ $(top_srcdir)/include/sys/vdev_disk.h \ @@ -498,6 +500,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/u8_textprep.h \ $(top_srcdir)/include/sys/uberblock.h \ $(top_srcdir)/include/sys/uberblock_impl.h \ + $(top_srcdir)/include/sys/uio_impl.h \ $(top_srcdir)/include/sys/unique.h \ $(top_srcdir)/include/sys/uuid.h \ $(top_srcdir)/include/sys/vdev_disk.h \ diff --git a/include/sys/uio_impl.h b/include/sys/uio_impl.h new file mode 100644 index 000000000..37e283da0 --- /dev/null +++ b/include/sys/uio_impl.h @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +#ifndef _SYS_UIO_IMPL_H +#define _SYS_UIO_IMPL_H + +#include + +extern int uiomove(void *, size_t, enum uio_rw, uio_t *); +extern void uio_prefaultpages(ssize_t, uio_t *); +extern int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *); +extern void uioskip(uio_t *, size_t); + +#endif /* _SYS_UIO_IMPL_H */ diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 44e3dd1d3..0ebacbc64 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -49,12 +49,11 @@ #include #include #include -#include +#include #include #include #include #include -#include #include #include #include diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 388b631e5..0c22b8cf7 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -22,6 +22,7 @@ libzpool_la_SOURCES = \ $(top_srcdir)/module/zcommon/zfs_fletcher.c \ $(top_srcdir)/module/zcommon/zfs_namecheck.c \ $(top_srcdir)/module/zcommon/zfs_prop.c \ + $(top_srcdir)/module/zcommon/zfs_uio.c \ $(top_srcdir)/module/zcommon/zpool_prop.c \ $(top_srcdir)/module/zcommon/zprop_common.c \ $(top_srcdir)/module/zfs/arc.c \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 209b8594e..17f70e6fe 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -105,10 +105,10 @@ libzpool_la_DEPENDENCIES = \ $(top_builddir)/lib/libspl/libspl.la am_libzpool_la_OBJECTS = kernel.lo taskq.lo util.lo zfs_comutil.lo \ zfs_deleg.lo zfs_fletcher.lo zfs_namecheck.lo zfs_prop.lo \ - zpool_prop.lo zprop_common.lo arc.lo bplist.lo bpobj.lo \ - dbuf.lo ddt.lo ddt_zap.lo dmu.lo dmu_diff.lo dmu_object.lo \ - dmu_objset.lo dmu_send.lo dmu_traverse.lo dmu_tx.lo \ - dmu_zfetch.lo dnode.lo dnode_sync.lo dsl_dataset.lo \ + zfs_uio.lo zpool_prop.lo zprop_common.lo arc.lo bplist.lo \ + bpobj.lo dbuf.lo ddt.lo ddt_zap.lo dmu.lo dmu_diff.lo \ + dmu_object.lo dmu_objset.lo dmu_send.lo dmu_traverse.lo \ + dmu_tx.lo dmu_zfetch.lo dnode.lo dnode_sync.lo dsl_dataset.lo \ dsl_deadlist.lo dsl_deleg.lo dsl_dir.lo dsl_pool.lo \ dsl_prop.lo dsl_scan.lo dsl_synctask.lo fm.lo gzip.lo lzjb.lo \ metaslab.lo refcount.lo rrwlock.lo sa.lo sha256.lo spa.lo \ @@ -344,6 +344,7 @@ libzpool_la_SOURCES = \ $(top_srcdir)/module/zcommon/zfs_fletcher.c \ $(top_srcdir)/module/zcommon/zfs_namecheck.c \ $(top_srcdir)/module/zcommon/zfs_prop.c \ + $(top_srcdir)/module/zcommon/zfs_uio.c \ $(top_srcdir)/module/zcommon/zpool_prop.c \ $(top_srcdir)/module/zcommon/zprop_common.c \ $(top_srcdir)/module/zfs/arc.c \ @@ -571,6 +572,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfs_namecheck.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfs_prop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfs_sa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfs_uio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfs_znode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zio.Plo@am__quote@ @@ -670,6 +672,14 @@ zfs_prop.lo: $(top_srcdir)/module/zcommon/zfs_prop.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o zfs_prop.lo `test -f '$(top_srcdir)/module/zcommon/zfs_prop.c' || echo '$(srcdir)/'`$(top_srcdir)/module/zcommon/zfs_prop.c +zfs_uio.lo: $(top_srcdir)/module/zcommon/zfs_uio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT zfs_uio.lo -MD -MP -MF $(DEPDIR)/zfs_uio.Tpo -c -o zfs_uio.lo `test -f '$(top_srcdir)/module/zcommon/zfs_uio.c' || echo '$(srcdir)/'`$(top_srcdir)/module/zcommon/zfs_uio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/zfs_uio.Tpo $(DEPDIR)/zfs_uio.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/module/zcommon/zfs_uio.c' object='zfs_uio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o zfs_uio.lo `test -f '$(top_srcdir)/module/zcommon/zfs_uio.c' || echo '$(srcdir)/'`$(top_srcdir)/module/zcommon/zfs_uio.c + zpool_prop.lo: $(top_srcdir)/module/zcommon/zpool_prop.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT zpool_prop.lo -MD -MP -MF $(DEPDIR)/zpool_prop.Tpo -c -o zpool_prop.lo `test -f '$(top_srcdir)/module/zcommon/zpool_prop.c' || echo '$(srcdir)/'`$(top_srcdir)/module/zcommon/zpool_prop.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/zpool_prop.Tpo $(DEPDIR)/zpool_prop.Plo diff --git a/module/zcommon/Makefile.in b/module/zcommon/Makefile.in index ee4864ffc..e564b77b4 100644 --- a/module/zcommon/Makefile.in +++ b/module/zcommon/Makefile.in @@ -13,4 +13,5 @@ $(MODULE)-objs += @top_srcdir@/module/zcommon/zprop_common.o $(MODULE)-objs += @top_srcdir@/module/zcommon/zfs_namecheck.o $(MODULE)-objs += @top_srcdir@/module/zcommon/zfs_comutil.o $(MODULE)-objs += @top_srcdir@/module/zcommon/zfs_fletcher.o +$(MODULE)-objs += @top_srcdir@/module/zcommon/zfs_uio.o $(MODULE)-objs += @top_srcdir@/module/zcommon/zpool_prop.o diff --git a/module/zcommon/zfs_uio.c b/module/zcommon/zfs_uio.c new file mode 100644 index 000000000..990464594 --- /dev/null +++ b/module/zcommon/zfs_uio.c @@ -0,0 +1,255 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +/* + * The uio support from OpenSolaris has been added as a short term + * work around. The hope is to adopt native Linux type and drop the + * use of uio's entirely. Under Linux they only add overhead and + * when possible we want to use native APIs for the ZPL layer. + */ +#ifdef _KERNEL + +#include +#include + +/* + * Move "n" bytes at byte address "p"; "rw" indicates the direction + * of the move, and the I/O parameters are provided in "uio", which is + * update to reflect the data which was moved. Returns 0 on success or + * a non-zero errno on failure. + */ +int +uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio) +{ + struct iovec *iov; + ulong_t cnt; + + while (n && uio->uio_resid) { + iov = uio->uio_iov; + cnt = MIN(iov->iov_len, n); + if (cnt == 0l) { + uio->uio_iov++; + uio->uio_iovcnt--; + continue; + } + switch (uio->uio_segflg) { + case UIO_USERSPACE: + case UIO_USERISPACE: + /* p = kernel data pointer + * iov->iov_base = user data pointer */ + + if (rw == UIO_READ) { + if (copy_to_user(iov->iov_base, p, cnt)) + return EFAULT; + /* error = xcopyout_nta(p, iov->iov_base, cnt, + * (uio->uio_extflg & UIO_COPY_CACHED)); */ + } else { + /* error = xcopyin_nta(iov->iov_base, p, cnt, + * (uio->uio_extflg & UIO_COPY_CACHED)); */ + if (copy_from_user(p, iov->iov_base, cnt)) + return EFAULT; + } + break; + case UIO_SYSSPACE: + if (rw == UIO_READ) + bcopy(p, iov->iov_base, cnt); + else + bcopy(iov->iov_base, p, cnt); + break; + } + iov->iov_base += cnt; + iov->iov_len -= cnt; + uio->uio_resid -= cnt; + uio->uio_loffset += cnt; + p = (caddr_t)p + cnt; + n -= cnt; + } + return (0); +} +EXPORT_SYMBOL(uiomove); + +#define fuword8(uptr, vptr) get_user((*vptr), (uptr)) + +/* + * Fault in the pages of the first n bytes specified by the uio structure. + * 1 byte in each page is touched and the uio struct is unmodified. Any + * error will terminate the process as this is only a best attempt to get + * the pages resident. + */ +void +uio_prefaultpages(ssize_t n, struct uio *uio) +{ + struct iovec *iov; + ulong_t cnt, incr; + caddr_t p; + uint8_t tmp; + int iovcnt; + + iov = uio->uio_iov; + iovcnt = uio->uio_iovcnt; + + while ((n > 0) && (iovcnt > 0)) { + cnt = MIN(iov->iov_len, n); + if (cnt == 0) { + /* empty iov entry */ + iov++; + iovcnt--; + continue; + } + n -= cnt; + /* + * touch each page in this segment. + */ + p = iov->iov_base; + while (cnt) { + switch (uio->uio_segflg) { + case UIO_USERSPACE: + case UIO_USERISPACE: + if (fuword8((uint8_t *) p, &tmp)) + return; + break; + case UIO_SYSSPACE: + bcopy(p, &tmp, 1); + break; + } + incr = MIN(cnt, PAGESIZE); + p += incr; + cnt -= incr; + } + /* + * touch the last byte in case it straddles a page. + */ + p--; + switch (uio->uio_segflg) { + case UIO_USERSPACE: + case UIO_USERISPACE: + if (fuword8((uint8_t *) p, &tmp)) + return; + break; + case UIO_SYSSPACE: + bcopy(p, &tmp, 1); + break; + } + iov++; + iovcnt--; + } +} +EXPORT_SYMBOL(uio_prefaultpages); + +/* + * same as uiomove() but doesn't modify uio structure. + * return in cbytes how many bytes were copied. + */ +int +uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes) +{ + struct iovec *iov; + ulong_t cnt; + int iovcnt; + + iovcnt = uio->uio_iovcnt; + *cbytes = 0; + + for (iov = uio->uio_iov; n && iovcnt; iov++, iovcnt--) { + cnt = MIN(iov->iov_len, n); + if (cnt == 0) + continue; + + switch (uio->uio_segflg) { + + case UIO_USERSPACE: + case UIO_USERISPACE: + /* p = kernel data pointer + * iov->iov_base = user data pointer */ + + if (rw == UIO_READ) { + /* * UIO_READ = copy data from kernel to user * */ + if (copy_to_user(iov->iov_base, p, cnt)) + return EFAULT; + /* error = xcopyout_nta(p, iov->iov_base, cnt, + * (uio->uio_extflg & UIO_COPY_CACHED)); */ + } else { + /* * UIO_WRITE = copy data from user to kernel * */ + /* error = xcopyin_nta(iov->iov_base, p, cnt, + * (uio->uio_extflg & UIO_COPY_CACHED)); */ + if (copy_from_user(p, iov->iov_base, cnt)) + return EFAULT; + } + break; + + case UIO_SYSSPACE: + if (rw == UIO_READ) + bcopy(p, iov->iov_base, cnt); + else + bcopy(iov->iov_base, p, cnt); + break; + } + p = (caddr_t)p + cnt; + n -= cnt; + *cbytes += cnt; + } + return (0); +} +EXPORT_SYMBOL(uiocopy); + +/* + * Drop the next n chars out of *uiop. + */ +void +uioskip(uio_t *uiop, size_t n) +{ + if (n > uiop->uio_resid) + return; + while (n != 0) { + iovec_t *iovp = uiop->uio_iov; + size_t niovb = MIN(iovp->iov_len, n); + + if (niovb == 0) { + uiop->uio_iov++; + uiop->uio_iovcnt--; + continue; + } + iovp->iov_base += niovb; + uiop->uio_loffset += niovb; + iovp->iov_len -= niovb; + uiop->uio_resid -= niovb; + n -= niovb; + } +} +EXPORT_SYMBOL(uioskip); +#endif /* _KERNEL */ From ab892c5f0ad7c2ee291693cf61dfc9601a2472d0 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 22 Dec 2010 10:07:03 -0800 Subject: [PATCH 25/75] Replace VOP_* calls with direct zfs_* calls These generic Solaris wrappers are no longer required. Simply directly call the correct zfs functions for clarity. --- module/zfs/zfs_replay.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index bd29ab9a1..2c258948b 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -310,7 +311,7 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, /* * All forms of zfs create (create, mkdir, mkxattrdir, symlink) * eventually end up in zfs_mknode(), which assigns the object's - * creation time and generation number. The generic VOP_CREATE() + * creation time and generation number. The generic zfs_create() * doesn't have either concept, so we smuggle the values inside * the vattr's otherwise unused va_ctime and va_nblocks fields. */ @@ -353,7 +354,7 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, lr->lr_uid, lr->lr_gid); } - error = VOP_CREATE(ZTOV(dzp), name, &xva.xva_vattr, + error = zfs_create(ZTOV(dzp), name, &xva.xva_vattr, 0, 0, &vp, kcred, vflg, NULL, &vsec); break; case TX_MKDIR_ACL: @@ -383,7 +384,7 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); } - error = VOP_MKDIR(ZTOV(dzp), name, &xva.xva_vattr, + error = zfs_mkdir(ZTOV(dzp), name, &xva.xva_vattr, &vp, kcred, NULL, vflg, &vsec); break; default: @@ -437,7 +438,7 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) /* * All forms of zfs create (create, mkdir, mkxattrdir, symlink) * eventually end up in zfs_mknode(), which assigns the object's - * creation time and generation number. The generic VOP_CREATE() + * creation time and generation number. The generic zfs_create() * doesn't have either concept, so we smuggle the values inside * the vattr's otherwise unused va_ctime and va_nblocks fields. */ @@ -482,7 +483,7 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) if (name == NULL) name = (char *)start; - error = VOP_CREATE(ZTOV(dzp), name, &xva.xva_vattr, + error = zfs_create(ZTOV(dzp), name, &xva.xva_vattr, 0, 0, &vp, kcred, vflg, NULL, NULL); break; case TX_MKDIR_ATTR: @@ -500,7 +501,7 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) if (name == NULL) name = (char *)(lr + 1); - error = VOP_MKDIR(ZTOV(dzp), name, &xva.xva_vattr, + error = zfs_mkdir(ZTOV(dzp), name, &xva.xva_vattr, &vp, kcred, NULL, vflg, NULL); break; case TX_MKXATTR: @@ -509,7 +510,7 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) case TX_SYMLINK: name = (char *)(lr + 1); link = name + strlen(name) + 1; - error = VOP_SYMLINK(ZTOV(dzp), name, &xva.xva_vattr, + error = zfs_symlink(ZTOV(dzp), name, &xva.xva_vattr, link, kcred, NULL, vflg); break; default: @@ -547,10 +548,10 @@ zfs_replay_remove(zfsvfs_t *zfsvfs, lr_remove_t *lr, boolean_t byteswap) switch ((int)lr->lr_common.lrc_txtype) { case TX_REMOVE: - error = VOP_REMOVE(ZTOV(dzp), name, kcred, NULL, vflg); + error = zfs_remove(ZTOV(dzp), name, kcred, NULL, vflg); break; case TX_RMDIR: - error = VOP_RMDIR(ZTOV(dzp), name, NULL, kcred, NULL, vflg); + error = zfs_rmdir(ZTOV(dzp), name, NULL, kcred, NULL, vflg); break; default: error = ENOTSUP; @@ -583,7 +584,7 @@ zfs_replay_link(zfsvfs_t *zfsvfs, lr_link_t *lr, boolean_t byteswap) if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; - error = VOP_LINK(ZTOV(dzp), ZTOV(zp), name, kcred, NULL, vflg); + error = zfs_link(ZTOV(dzp), ZTOV(zp), name, kcred, NULL, vflg); VN_RELE(ZTOV(zp)); VN_RELE(ZTOV(dzp)); @@ -614,7 +615,7 @@ zfs_replay_rename(zfsvfs_t *zfsvfs, lr_rename_t *lr, boolean_t byteswap) if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; - error = VOP_RENAME(ZTOV(sdzp), sname, ZTOV(tdzp), tname, kcred, + error = zfs_rename(ZTOV(sdzp), sname, ZTOV(tdzp), tname, kcred, NULL, vflg); VN_RELE(ZTOV(tdzp)); @@ -753,7 +754,7 @@ zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) fl.l_start = lr->lr_offset; fl.l_len = lr->lr_length; - error = VOP_SPACE(ZTOV(zp), F_FREESP, &fl, FWRITE | FOFFMAX, + error = zfs_space(ZTOV(zp), F_FREESP, &fl, FWRITE | FOFFMAX, lr->lr_offset, kcred, NULL); VN_RELE(ZTOV(zp)); @@ -804,7 +805,7 @@ zfs_replay_setattr(zfsvfs_t *zfsvfs, lr_setattr_t *lr, boolean_t byteswap) zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); - error = VOP_SETATTR(ZTOV(zp), vap, 0, kcred, NULL); + error = zfs_setattr(ZTOV(zp), vap, 0, kcred, NULL); zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfsvfs->z_fuid_replay = NULL; @@ -836,7 +837,7 @@ zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) vsa.vsa_aclflags = 0; vsa.vsa_aclentp = ace; - error = VOP_SETSECATTR(ZTOV(zp), &vsa, 0, kcred, NULL); + error = zfs_setsecattr(ZTOV(zp), &vsa, 0, kcred, NULL); VN_RELE(ZTOV(zp)); @@ -894,7 +895,7 @@ zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap) lr->lr_fuidcnt, lr->lr_domcnt, 0, 0); } - error = VOP_SETSECATTR(ZTOV(zp), &vsa, 0, kcred, NULL); + error = zfs_setsecattr(ZTOV(zp), &vsa, 0, kcred, NULL); if (zfsvfs->z_fuid_replay) zfs_fuid_info_free(zfsvfs->z_fuid_replay); From 8299a1f41eb4761cd25ea821830295a6f32be581 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 18 Jan 2011 11:42:25 -0800 Subject: [PATCH 26/75] Add Linux Compat Infrastructure Lay the initial ground work for a include/linux/ compatibility directory. This was less critical in the past because the bulk of the ZFS code consumes the Solaris API via the SPL. This API was stable and the bulk Linux API differences were handled in the SPL. However, with the addition of a full Posix layer written directly against the Linux APIs we are going to need more compatibility code. It makes sense that all this code should be cleanly located in one place. Subsequent patches should move the existing zvol and vdev_disk compatibility code in to this directory. --- configure | 3 +- configure.ac | 1 + include/Makefile.am | 2 +- include/Makefile.in | 2 +- include/linux/Makefile.am | 18 ++ include/linux/Makefile.in | 568 ++++++++++++++++++++++++++++++++++ include/linux/dcache_compat.h | 33 ++ include/sys/zfs_context.h | 1 + 8 files changed, 625 insertions(+), 3 deletions(-) create mode 100644 include/linux/Makefile.am create mode 100644 include/linux/Makefile.in create mode 100644 include/linux/dcache_compat.h diff --git a/configure b/configure index d96270472..e76d64ddf 100755 --- a/configure +++ b/configure @@ -18945,7 +18945,7 @@ fi $as_echo "$enable_debug" >&6; } -ac_config_files="$ac_config_files Makefile etc/Makefile man/Makefile man/man8/Makefile lib/Makefile lib/libspl/Makefile lib/libspl/asm-generic/Makefile lib/libspl/asm-i386/Makefile lib/libspl/asm-x86_64/Makefile lib/libspl/include/Makefile lib/libspl/include/ia32/Makefile lib/libspl/include/ia32/sys/Makefile lib/libspl/include/rpc/Makefile lib/libspl/include/sys/Makefile lib/libspl/include/sys/sysevent/Makefile lib/libspl/include/sys/dktp/Makefile lib/libspl/include/util/Makefile lib/libavl/Makefile lib/libefi/Makefile lib/libnvpair/Makefile lib/libunicode/Makefile lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zfs/Makefile cmd/zinject/Makefile cmd/zpool/Makefile cmd/zpool_id/Makefile cmd/zpool_layout/Makefile cmd/ztest/Makefile cmd/zpios/Makefile module/Makefile module/avl/Makefile module/nvpair/Makefile module/unicode/Makefile module/zcommon/Makefile module/zfs/Makefile module/zpios/Makefile include/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile include/sys/fm/fs/Makefile scripts/Makefile scripts/zpios-profile/Makefile scripts/zpios-test/Makefile scripts/zpool-config/Makefile scripts/zpool-layout/Makefile scripts/common.sh zfs.spec zfs-modules.spec zfs-script-config.sh" +ac_config_files="$ac_config_files Makefile etc/Makefile man/Makefile man/man8/Makefile lib/Makefile lib/libspl/Makefile lib/libspl/asm-generic/Makefile lib/libspl/asm-i386/Makefile lib/libspl/asm-x86_64/Makefile lib/libspl/include/Makefile lib/libspl/include/ia32/Makefile lib/libspl/include/ia32/sys/Makefile lib/libspl/include/rpc/Makefile lib/libspl/include/sys/Makefile lib/libspl/include/sys/sysevent/Makefile lib/libspl/include/sys/dktp/Makefile lib/libspl/include/util/Makefile lib/libavl/Makefile lib/libefi/Makefile lib/libnvpair/Makefile lib/libunicode/Makefile lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zfs/Makefile cmd/zinject/Makefile cmd/zpool/Makefile cmd/zpool_id/Makefile cmd/zpool_layout/Makefile cmd/ztest/Makefile cmd/zpios/Makefile module/Makefile module/avl/Makefile module/nvpair/Makefile module/unicode/Makefile module/zcommon/Makefile module/zfs/Makefile module/zpios/Makefile include/Makefile include/linux/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile include/sys/fm/fs/Makefile scripts/Makefile scripts/zpios-profile/Makefile scripts/zpios-test/Makefile scripts/zpool-config/Makefile scripts/zpool-layout/Makefile scripts/common.sh zfs.spec zfs-modules.spec zfs-script-config.sh" cat >confcache <<\_ACEOF @@ -19902,6 +19902,7 @@ do "module/zfs/Makefile") CONFIG_FILES="$CONFIG_FILES module/zfs/Makefile" ;; "module/zpios/Makefile") CONFIG_FILES="$CONFIG_FILES module/zpios/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "include/linux/Makefile") CONFIG_FILES="$CONFIG_FILES include/linux/Makefile" ;; "include/sys/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/Makefile" ;; "include/sys/fs/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fs/Makefile" ;; "include/sys/fm/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fm/Makefile" ;; diff --git a/configure.ac b/configure.ac index 593271061..efebf71e9 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,7 @@ AC_CONFIG_FILES([ module/zfs/Makefile module/zpios/Makefile include/Makefile + include/linux/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile diff --git a/include/Makefile.am b/include/Makefile.am index 0926c6a69..1d7493bb5 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sys +SUBDIRS = linux sys COMMON_H = \ $(top_srcdir)/include/zfs_comutil.h \ diff --git a/include/Makefile.in b/include/Makefile.in index 851bd8a12..f87cd7929 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -332,7 +332,7 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = sys +SUBDIRS = linux sys COMMON_H = \ $(top_srcdir)/include/zfs_comutil.h \ $(top_srcdir)/include/zfs_deleg.h \ diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am new file mode 100644 index 000000000..4ccd7b124 --- /dev/null +++ b/include/linux/Makefile.am @@ -0,0 +1,18 @@ +COMMON_H = + +KERNEL_H = \ + $(top_srcdir)/include/linux/dcache_compat.h + +USER_H = + +EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H) + +if CONFIG_USER +libzfsdir = $(includedir)/libzfs/linux +libzfs_HEADERS = $(COMMON_H) $(USER_H) +endif + +if CONFIG_KERNEL +kerneldir = /usr/src/zfs-$(ZFS_META_VERSION)/$(LINUX_VERSION)/linux +kernel_HEADERS = $(COMMON_H) $(KERNEL_H) +endif diff --git a/include/linux/Makefile.in b/include/linux/Makefile.in new file mode 100644 index 000000000..51d0a6d5b --- /dev/null +++ b/include/linux/Makefile.in @@ -0,0 +1,568 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = include/linux +DIST_COMMON = $(am__kernel_HEADERS_DIST) $(libzfs_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = \ + $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \ + $(top_srcdir)/config/kernel-bdev-logical-size.m4 \ + $(top_srcdir)/config/kernel-bio-empty-barrier.m4 \ + $(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \ + $(top_srcdir)/config/kernel-bio-failfast.m4 \ + $(top_srcdir)/config/kernel-bio-rw-syncio.m4 \ + $(top_srcdir)/config/kernel-blk-end-request.m4 \ + $(top_srcdir)/config/kernel-blk-fetch-request.m4 \ + $(top_srcdir)/config/kernel-blk-requeue-request.m4 \ + $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ + $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ + $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-get-disk-ro.m4 \ + $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ + $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ + $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ + $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel.m4 \ + $(top_srcdir)/config/user-arch.m4 \ + $(top_srcdir)/config/user-frame-larger-than.m4 \ + $(top_srcdir)/config/user-ioctl.m4 \ + $(top_srcdir)/config/user-libblkid.m4 \ + $(top_srcdir)/config/user-libuuid.m4 \ + $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ + $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ + $(top_srcdir)/config/zfs-build.m4 \ + $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/zfs_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +am__kernel_HEADERS_DIST = $(top_srcdir)/include/linux/dcache_compat.h +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)" +HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALIEN = @ALIEN@ +ALIEN_VERSION = @ALIEN_VERSION@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_CFLAGS = @DEBUG_CFLAGS@ +DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@ +DEFAULT_PACKAGE = @DEFAULT_PACKAGE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DPKG = @DPKG@ +DPKGBUILD = @DPKGBUILD@ +DPKGBUILD_VERSION = @DPKGBUILD_VERSION@ +DPKG_VERSION = @DPKG_VERSION@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FRAME_LARGER_THAN = @FRAME_LARGER_THAN@ +GREP = @GREP@ +HAVE_ALIEN = @HAVE_ALIEN@ +HAVE_DPKG = @HAVE_DPKG@ +HAVE_DPKGBUILD = @HAVE_DPKGBUILD@ +HAVE_RPM = @HAVE_RPM@ +HAVE_RPMBUILD = @HAVE_RPMBUILD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNELCPPFLAGS = @KERNELCPPFLAGS@ +KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBLKID = @LIBBLKID@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ +LIBTOOL = @LIBTOOL@ +LIBUUID = @LIBUUID@ +LINUX = @LINUX@ +LINUX_OBJ = @LINUX_OBJ@ +LINUX_SYMBOLS = @LINUX_SYMBOLS@ +LINUX_VERSION = @LINUX_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +RPMBUILD = @RPMBUILD@ +RPMBUILD_VERSION = @RPMBUILD_VERSION@ +RPM_VERSION = @RPM_VERSION@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPL = @SPL@ +SPL_OBJ = @SPL_OBJ@ +SPL_SYMBOLS = @SPL_SYMBOLS@ +SPL_VERSION = @SPL_VERSION@ +STRIP = @STRIP@ +TARGET_ASM_DIR = @TARGET_ASM_DIR@ +VENDOR = @VENDOR@ +VERSION = @VERSION@ +ZFS_CONFIG = @ZFS_CONFIG@ +ZFS_META_ALIAS = @ZFS_META_ALIAS@ +ZFS_META_AUTHOR = @ZFS_META_AUTHOR@ +ZFS_META_DATA = @ZFS_META_DATA@ +ZFS_META_LICENSE = @ZFS_META_LICENSE@ +ZFS_META_LT_AGE = @ZFS_META_LT_AGE@ +ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@ +ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@ +ZFS_META_NAME = @ZFS_META_NAME@ +ZFS_META_RELEASE = @ZFS_META_RELEASE@ +ZFS_META_VERSION = @ZFS_META_VERSION@ +ZLIB = @ZLIB@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +COMMON_H = +KERNEL_H = \ + $(top_srcdir)/include/linux/dcache_compat.h + +USER_H = +EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H) +@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/linux +@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H) +@CONFIG_KERNEL_TRUE@kerneldir = /usr/src/zfs-$(ZFS_META_VERSION)/$(LINUX_VERSION)/linux +@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/linux/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/linux/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-kernelHEADERS: $(kernel_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(kerneldir)" || $(MKDIR_P) "$(DESTDIR)$(kerneldir)" + @list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \ + done + +uninstall-kernelHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(kerneldir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(kerneldir)" && rm -f $$files +install-libzfsHEADERS: $(libzfs_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(libzfsdir)" || $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" + @list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \ + done + +uninstall-libzfsHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libzfsdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libzfsdir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-kernelHEADERS install-libzfsHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-kernelHEADERS install-libzfsHEADERS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-kernelHEADERS \ + uninstall-libzfsHEADERS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/include/linux/dcache_compat.h b/include/linux/dcache_compat.h new file mode 100644 index 000000000..a624d4dd9 --- /dev/null +++ b/include/linux/dcache_compat.h @@ -0,0 +1,33 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (C) 2011 Lawrence Livermore National Security, LLC. + */ + +#ifndef _ZFS_DCACHE_H +#define _ZFS_DCACHE_H + +#include + +#define dname(dentry) ((char *)((dentry)->d_name.name)) + +#endif /* _ZFS_DCACHE_H */ diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 0ebacbc64..a0165bb2f 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -57,6 +57,7 @@ #include #include #include +#include #else /* _KERNEL */ From 3fc050aaf2bc2e11844268ae0c091e6eb56108e5 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 15:26:17 -0800 Subject: [PATCH 27/75] Init/destroy tsd Add missing tsd_destroy() call for rrw_tsd_key to avoid a leak. --- module/zfs/zfs_ioctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 17f3ff60b..6a7623cae 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -5196,10 +5196,8 @@ zfs_detach(void) list_destroy(&zfsdev_state_list); } -#ifdef HAVE_ZPL uint_t zfs_fsyncer_key; extern uint_t rrw_tsd_key; -#endif #ifdef DEBUG #define ZFS_DEBUG_STR " (DEBUG mode)" @@ -5262,6 +5260,7 @@ _fini(void) mutex_destroy(&zfs_share_lock); #endif /* HAVE_SHARE */ tsd_destroy(&zfs_fsyncer_key); + tsd_destroy(&rrw_tsd_key); printk(KERN_NOTICE "ZFS: Unloaded ZFS Filesystem v%s%s\n", ZFS_META_VERSION, ZFS_DEBUG_STR); From a405c8a665bf7d96880c97bcb783cf84d04e3e76 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 17 Dec 2010 15:21:18 -0800 Subject: [PATCH 28/75] ACL related changes A small collection of ACL related changes related to not supporting fuid mapping. This whole are will need to be closely investigated. --- include/sys/zfs_fuid.h | 2 -- module/zfs/zfs_acl.c | 10 +++++++--- module/zfs/zfs_fuid.c | 22 ++++++++++++++++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/sys/zfs_fuid.h b/include/sys/zfs_fuid.h index d2989c852..91650a22d 100644 --- a/include/sys/zfs_fuid.h +++ b/include/sys/zfs_fuid.h @@ -99,7 +99,6 @@ typedef struct zfs_fuid_info { } zfs_fuid_info_t; #ifdef _KERNEL -#ifdef HAVE_ZPL struct znode; extern uid_t zfs_fuid_map_id(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t); extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t, @@ -119,7 +118,6 @@ extern int zfs_fuid_find_by_domain(zfsvfs_t *, const char *domain, char **retdomain, boolean_t addok); extern const char *zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx); extern void zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx); -#endif /* HAVE_ZPL */ #endif char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t); diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index ea209ba52..45ec20647 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -22,7 +22,6 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ -#ifdef HAVE_ZPL #include #include @@ -1726,7 +1725,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, int error; zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_acl_t *paclp; +#ifdef HAVE_KSID gid_t gid; +#endif /* HAVE_KSID */ boolean_t need_chmod = B_TRUE; boolean_t inherited = B_FALSE; @@ -1737,6 +1738,10 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, if ((error = zfs_vsec_2_aclp(zfsvfs, vap->va_type, vsecp, cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0) return (error); + + acl_ids->z_fuid = vap->va_uid; + acl_ids->z_fgid = vap->va_gid; +#ifdef HAVE_KSID /* * Determine uid and gid. */ @@ -1790,6 +1795,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, } } } +#endif /* HAVE_KSID */ /* * If we're creating a directory, and the parent directory has the @@ -2793,5 +2799,3 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, return (error); } - -#endif /* HAVE_ZPL */ diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index 97fceea00..a5741185a 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -192,7 +192,6 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx) } #ifdef _KERNEL -#ifdef HAVE_ZPL /* * Load the fuid table(s) into memory. */ @@ -397,6 +396,7 @@ uid_t zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, cred_t *cr, zfs_fuid_type_t type) { +#ifdef HAVE_KSID uint32_t index = FUID_INDEX(fuid); const char *domain; uid_t id; @@ -415,6 +415,12 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, FUID_RID(fuid), &id); } return (id); +#else + if(type == ZFS_OWNER || type == ZFS_ACE_USER) + return (crgetuid(cr)); + else + return (crgetgid(cr)); +#endif /* HAVE_KSID */ } /* @@ -483,6 +489,7 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid, } } +#ifdef HAVE_KSID /* * Create a file system FUID, based on information in the users cred * @@ -535,6 +542,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, return (FUID_ENCODE(idx, rid)); } +#endif /* HAVE_KSID */ /* * Create a file system FUID for an ACL ace @@ -552,6 +560,7 @@ uint64_t zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp) { +#ifdef HAVE_KSID const char *domain; char *kdomain; uint32_t fuid_idx = FUID_INDEX(id); @@ -630,6 +639,12 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, kmem_free(zfuid, sizeof (zfs_fuid_t)); } return (FUID_ENCODE(idx, rid)); +#else + if (type == ZFS_OWNER) + return crgetuid(cr); + else + return crgetgid(cr); +#endif } void @@ -697,6 +712,7 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp) boolean_t zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) { +#ifdef HAVE_KSID ksid_t *ksid = crgetsid(cr, KSID_GROUP); ksidlist_t *ksidlist = crgetsidlist(cr); uid_t gid; @@ -738,6 +754,9 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) */ gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP); return (groupmember(gid, cr)); +#else + return (B_TRUE); +#endif } void @@ -754,5 +773,4 @@ zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx) FUID_SIZE_ESTIMATE(zfsvfs)); } } -#endif /* HAVE_ZPL */ #endif From 10c6047ea56445a87d8ce1397ac2d2caa97719ca Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 21 Dec 2010 16:28:11 -0800 Subject: [PATCH 29/75] Enable zfs_znode compilation Basic compilation of the bulk of zfs_znode.c has been enabled. After much consideration it was decided to convert the existing vnode based interfaces to more friendly Linux interfaces. The following commits will systematically replace update the requiter interfaces. There are of course pros and cons to this decision. Pros: * This simplifies intergration with Linux in the long term. There is no longer any need to manage vnodes which are a foreign concept to the Linux VFS. * Improved long term maintainability. * Minor performance improvements by removing vnode overhead. Cons: * Added work in the short term to modify multiple ZFS interfaces. * Harder to pull in changes if we ever see any new code from Solaris. * Mixed Solaris and Linux interfaces in some ZFS code. --- module/zfs/sa.c | 4 ---- module/zfs/zfs_znode.c | 35 +++++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/module/zfs/sa.c b/module/zfs/sa.c index ee1140ffb..c90008252 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -1436,7 +1436,6 @@ sa_lookup(sa_handle_t *hdl, sa_attr_type_t attr, void *buf, uint32_t buflen) int sa_lookup_uio(sa_handle_t *hdl, sa_attr_type_t attr, uio_t *uio) { -#ifdef HAVE_ZPL int error; sa_bulk_attr_t bulk; @@ -1453,9 +1452,6 @@ sa_lookup_uio(sa_handle_t *hdl, sa_attr_type_t attr, uio_t *uio) } mutex_exit(&hdl->sa_lock); return (error); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } #endif diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 137a06810..72a077d08 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -88,7 +88,6 @@ * (such as VFS logic) that will not compile easily in userland. */ #ifdef _KERNEL -#ifdef HAVE_ZPL /* * Needed to close a small window in zfs_znode_move() that allows the zfsvfs to * be freed before it can be safely accessed. @@ -97,17 +96,6 @@ krwlock_t zfsvfs_lock; static kmem_cache_t *znode_cache = NULL; -/*ARGSUSED*/ -static void -znode_evict_error(dmu_buf_t *dbuf, void *user_ptr) -{ - /* - * We should never drop all dbuf refs without first clearing - * the eviction callback. - */ - panic("evicting znode %p\n", user_ptr); -} - /*ARGSUSED*/ static int zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) @@ -179,7 +167,9 @@ zfs_znode_fini(void) /* * Cleanup vfs & vnode ops */ +#ifdef HAVE_ZPL zfs_remove_op_tables(); +#endif /* HAVE_ZPL */ /* * Cleanup zcache @@ -190,6 +180,7 @@ zfs_znode_fini(void) rw_destroy(&zfsvfs_lock); } +#ifdef HAVE_ZPL struct vnodeops *zfs_dvnodeops; struct vnodeops *zfs_fvnodeops; struct vnodeops *zfs_symvnodeops; @@ -346,6 +337,8 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) #define MAXMIN64 0xffffffffUL #endif +#endif /* HAVE_ZPL */ + /* * Create special expldev for ZFS private use. * Can't use standard expldev since it doesn't do @@ -443,11 +436,13 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, dmu_object_type_t obj_type, sa_handle_t *hdl) { znode_t *zp; +#ifdef HAVE_ZPL vnode_t *vp; uint64_t mode; uint64_t parent; sa_bulk_attr_t bulk[9]; int count = 0; +#endif /* HAVE_ZPL */ zp = kmem_cache_alloc(znode_cache, KM_SLEEP); @@ -468,6 +463,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, zp->z_seq = 0x7A4653; zp->z_sync_cnt = 0; +#ifdef HAVE_ZPL vp = ZTOV(zp); vn_reinit(vp); @@ -542,7 +538,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, vn_setops(vp, zfs_evnodeops); break; } - +#endif /* HAVE_ZPL */ mutex_enter(&zfsvfs->z_znodes_lock); list_insert_tail(&zfsvfs->z_all_znodes, zp); membar_producer(); @@ -835,6 +831,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) { +#ifdef HAVE_XVATTR xoptattr_t *xoap; xoap = xva_getxoptattr(xvap); @@ -921,6 +918,7 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zp->z_pflags, tx); XVA_SET_RTN(xvap, XAT_SPARSE); } +#endif /* HAVE_XVATTR */ } int @@ -1249,6 +1247,7 @@ zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy); } +#ifdef HAVE_ZPL /* * This is a dummy interface used when pvn_vplist_dirty() should *not* * be calling back into the fs for a putpage(). E.g.: when truncating @@ -1262,6 +1261,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, ASSERT(0); return (0); } +#endif /* HAVE_ZPL */ /* * Increase the file length @@ -1393,7 +1393,9 @@ static int zfs_trunc(znode_t *zp, uint64_t end) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; +#ifdef HAVE_ZPL vnode_t *vp = ZTOV(zp); +#endif /* HAVE_ZPL */ dmu_tx_t *tx; rl_t *rl; int error; @@ -1447,6 +1449,7 @@ top: dmu_tx_commit(tx); +#ifdef HAVE_ZPL /* * Clear any mapped pages in the truncated region. This has to * happen outside of the transaction to avoid the possibility of @@ -1470,6 +1473,7 @@ top: B_INVAL | B_TRUNC, NULL); ASSERT(error == 0); } +#endif /* HAVE_ZPL */ zfs_range_unlock(rl); @@ -1491,7 +1495,9 @@ top: int zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) { +#ifdef HAVE_ZPL vnode_t *vp = ZTOV(zp); +#endif /* HAVE_ZPL */ dmu_tx_t *tx; zfsvfs_t *zfsvfs = zp->z_zfsvfs; zilog_t *zilog = zfsvfs->z_log; @@ -1513,6 +1519,7 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) return (error); } +#ifdef HAVE_ZPL /* * Check for any locks in the region to be freed. */ @@ -1522,6 +1529,7 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) if (error = chklock(vp, FWRITE, off, length, flag, NULL)) return (error); } +#endif /* HAVE_ZPL */ if (len == 0) { error = zfs_trunc(zp, off); @@ -1560,7 +1568,6 @@ log: dmu_tx_commit(tx); return (0); } -#endif /* HAVE_ZPL */ void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) From 7304b6e50f656fbf4b126a4e94deac174133851c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 13:16:12 -0800 Subject: [PATCH 30/75] VFS: Integrate zfs_znode_alloc() Under Linux the convention for filesystem specific data structure is to embed it along with the generic vfs data structure. This differs significantly from Solaris. Since we want to integrates as cleanly with the Linux VFS as possible. This changes modifies zfs_znode_alloc() to allocate a znode with an embedded inode for use with the generic VFS. This is done by calling iget_locked() which will allocate a new inode if needed by calling sb->alloc_inode(). This function allocates enough memory for a znode_t by returns a pointer to the inode structure for Linux's VFS. This function is also responsible for setting the callback znode->z_set_ops_inodes() which is used to register the correct handlers for the inode. --- include/sys/zfs_znode.h | 11 +++++- module/zfs/zfs_znode.c | 88 +++++++++++++---------------------------- 2 files changed, 37 insertions(+), 62 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index aa1f449ac..356092169 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -211,6 +211,8 @@ typedef struct znode { list_node_t z_link_node; /* all znodes in fs link */ sa_handle_t *z_sa_hdl; /* handle to sa data */ boolean_t z_is_sa; /* are we native sa? */ + void (*z_set_ops_inode) (struct inode *); /* set inode ops */ + struct inode z_inode; /* generic vfs inode */ } znode_t; @@ -231,13 +233,18 @@ typedef struct znode { */ /* - * Convert between znode pointers and vnode pointers + * Convert between znode pointers and inode pointers */ +#define ZTOI(ZP) (&((ZP)->z_inode)) +#define ITOZ(IP) (container_of((IP), znode_t, z_inode)) + +/* XXX - REMOVE ME ONCE THE OTHER BUILD ISSUES ARE RESOLVED */ #define ZTOV(ZP) ((ZP)->z_vnode) #define VTOZ(VP) ((znode_t *)(VP)->v_data) + /* - * ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation. + * ZFS_ENTER() is called on entry to each ZFS inode and vfs operation. * ZFS_EXIT() must be called before exitting the vop. * ZFS_VERIFY_ZP() verifies the znode is valid. */ diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 72a077d08..7823bc5e7 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -425,7 +425,7 @@ zfs_znode_dmu_fini(znode_t *zp) } /* - * Construct a new znode/vnode and intialize. + * Construct a new znode+inode and initialize. * * This does not do a call to dmu_set_user() that is * up to the caller to do, in case you don't want to @@ -436,16 +436,19 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, dmu_object_type_t obj_type, sa_handle_t *hdl) { znode_t *zp; -#ifdef HAVE_ZPL - vnode_t *vp; - uint64_t mode; + struct inode *inode; uint64_t parent; sa_bulk_attr_t bulk[9]; int count = 0; -#endif /* HAVE_ZPL */ - zp = kmem_cache_alloc(znode_cache, KM_SLEEP); + ASSERT(zfsvfs != NULL); + ASSERT(zfsvfs->z_vfs != NULL); + ASSERT(zfsvfs->z_vfs->mnt_sb != NULL); + inode = iget_locked(zfsvfs->z_vfs->mnt_sb, db->db_object); + zp = ITOZ(inode); + + ASSERT(inode->i_state & I_NEW); ASSERT(zp->z_dirlocks == NULL); ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); zp->z_moved = 0; @@ -463,21 +466,20 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, zp->z_seq = 0x7A4653; zp->z_sync_cnt = 0; -#ifdef HAVE_ZPL - vp = ZTOV(zp); - vn_reinit(vp); - zfs_znode_sa_init(zfsvfs, zp, db, obj_type, hdl); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, &zp->z_gen, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, + &zp->z_mode, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, + &zp->z_gen, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, &zp->z_size, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, &zp->z_links, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, &zp->z_pflags, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, + &parent, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, &zp->z_atime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, @@ -488,57 +490,23 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) { if (hdl == NULL) sa_handle_destroy(zp->z_sa_hdl); - kmem_cache_free(znode_cache, zp); + iput(inode); return (NULL); } - zp->z_mode = mode; - vp->v_vfsp = zfsvfs->z_parent->z_vfs; - - vp->v_type = IFTOVT((mode_t)mode); - - switch (vp->v_type) { - case VDIR: - if (zp->z_pflags & ZFS_XATTR) { - vn_setops(vp, zfs_xdvnodeops); - vp->v_flag |= V_XATTRDIR; - } else { - vn_setops(vp, zfs_dvnodeops); - } - zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ - break; - case VBLK: - case VCHR: - { - uint64_t rdev; - VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs), - &rdev, sizeof (rdev)) == 0); - - vp->v_rdev = zfs_cmpldev(rdev); - } - /*FALLTHROUGH*/ - case VFIFO: - case VSOCK: - case VDOOR: - vn_setops(vp, zfs_fvnodeops); - break; - case VREG: - vp->v_flag |= VMODSORT; - if (parent == zfsvfs->z_shares_dir) { - ASSERT(zp->z_uid == 0 && zp->z_gid == 0); - vn_setops(vp, zfs_sharevnodeops); - } else { - vn_setops(vp, zfs_fvnodeops); - } - break; - case VLNK: - vn_setops(vp, zfs_symvnodeops); - break; - default: - vn_setops(vp, zfs_evnodeops); - break; + inode->i_mode = (umode_t)zp->z_mode; + if ((S_ISCHR(inode->i_mode)) || (S_ISBLK(inode->i_mode))) { + uint64_t rdev; + VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs), + &rdev, sizeof (rdev)) == 0); + inode->i_rdev = zfs_cmpldev(rdev); } -#endif /* HAVE_ZPL */ + + /* zp->z_set_ops_inode() must be set in sb->alloc_inode() */ + ASSERT(zp->z_set_ops_inode != NULL); + zp->z_set_ops_inode(inode); + unlock_new_inode(inode); + mutex_enter(&zfsvfs->z_znodes_lock); list_insert_tail(&zfsvfs->z_all_znodes, zp); membar_producer(); From 960e08fe3e2cdf5217996b9f42a01f7e20f2b97a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 14:27:30 -0800 Subject: [PATCH 31/75] VFS: Add zfs_inode_update() helper For the moment we have left ZFS unchanged and it updates many values as part of the znode. However, some of these values should be set in the inode. For the moment this is handled by adding a function called zfs_inode_update() which updates the inode based on the znode. This is considered a workaround until we can systematically go through the ZFS code and have it directly update the inode. At which point zfs_update_inode() can be dropped entirely. Keeping two copies of the same data isn't only inefficient it's a breeding ground for bugs. --- include/sys/zfs_znode.h | 1 + module/zfs/zfs_vfsops.c | 3 +++ module/zfs/zfs_vnops.c | 33 ++++++++++++++++++++++++++++++-- module/zfs/zfs_znode.c | 42 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 356092169..4dbecb4b5 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -326,6 +326,7 @@ extern dev_t zfs_cmpldev(uint64_t); extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value); extern int zfs_get_stats(objset_t *os, nvlist_t *nv); extern void zfs_znode_dmu_fini(znode_t *); +extern void zfs_inode_update(znode_t *); extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *dzp, znode_t *zp, char *name, vsecattr_t *, zfs_fuid_info_t *, diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index ef433125a..4545c20e2 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1942,6 +1942,9 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) } *vpp = ZTOV(zp); + if (*vpp) + zfs_inode_update(VTOZ(*vpp)); + ZFS_EXIT(zfsvfs); return (0); } diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index b666ee39c..e5e187b15 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -564,6 +564,7 @@ out: zfs_range_unlock(rl); ZFS_ACCESSTIME_STAMP(zfsvfs, zp); + zfs_inode_update(zp); ZFS_EXIT(zfsvfs); return (error); } @@ -938,6 +939,7 @@ again: zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, zp->z_id); + zfs_inode_update(zp); ZFS_EXIT(zfsvfs); return (0); } @@ -1266,8 +1268,12 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, } error = zfs_dirlook(zdp, nm, vpp, flags, direntflags, realpnp); - if (error == 0) + if (error == 0) { + if (*vpp) + zfs_inode_update(VTOZ(*vpp)); + error = specvp_check(vpp, cr); + } ZFS_EXIT(zfsvfs); return (error); @@ -1523,6 +1529,8 @@ out: if (zp) VN_RELE(ZTOV(zp)); } else { + zfs_inode_update(dzp); + zfs_inode_update(zp); *vpp = ZTOV(zp); error = specvp_check(vpp, cr); } @@ -1753,6 +1761,10 @@ out: pn_free(realnmp); zfs_dirent_unlock(dl); + zfs_inode_update(dzp); + zfs_inode_update(zp); + if (xzp) + zfs_inode_update(xzp); if (!delete_now) VN_RELE(vp); @@ -1945,6 +1957,8 @@ top: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); + zfs_inode_update(dzp); + zfs_inode_update(zp); ZFS_EXIT(zfsvfs); return (0); } @@ -2074,6 +2088,8 @@ out: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); + zfs_inode_update(dzp); + zfs_inode_update(zp); ZFS_EXIT(zfsvfs); return (error); } @@ -3227,6 +3243,7 @@ out: } else { err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); dmu_tx_commit(tx); + zfs_inode_update(zp); } out2: @@ -3674,13 +3691,19 @@ out: zfs_dirent_unlock(sdl); zfs_dirent_unlock(tdl); + zfs_inode_update(sdzp); if (sdzp == tdzp) rw_exit(&sdzp->z_name_lock); + if (sdzp != tdzp) + zfs_inode_update(tdzp); + zfs_inode_update(szp); VN_RELE(ZTOV(szp)); - if (tzp) + if (tzp) { + zfs_inode_update(tzp); VN_RELE(ZTOV(tzp)); + } if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); @@ -3828,6 +3851,9 @@ top: txtype |= TX_CI; zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link); + zfs_inode_update(dzp); + zfs_inode_update(zp); + zfs_acl_ids_free(&acl_ids); dmu_tx_commit(tx); @@ -3882,6 +3908,7 @@ zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct) ZFS_ACCESSTIME_STAMP(zfsvfs, zp); + zfs_inode_update(zp); ZFS_EXIT(zfsvfs); return (error); } @@ -4037,6 +4064,8 @@ top: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); + zfs_inode_update(dzp); + zfs_inode_update(szp); ZFS_EXIT(zfsvfs); return (error); } diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 7823bc5e7..0ae16448f 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -521,6 +521,47 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, return (zp); } +/* + * Update the embedded inode given the znode. We should work toward + * eliminating this function as soon as possible by removing values + * which are duplicated between the znode and inode. If the generic + * inode has the correct field it should be used, and the ZFS code + * updated to access the inode. This can be done incrementally. + */ +void +zfs_inode_update(znode_t *zp) +{ + zfsvfs_t *zfsvfs; + struct inode *inode; + uint32_t blksize; + uint64_t atime[2], mtime[2], ctime[2]; + + ASSERT(zp != NULL); + zfsvfs = zp->z_zfsvfs; + inode = ZTOI(zp); + + sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), &atime, 16); + sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zfsvfs), &mtime, 16); + sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zfsvfs), &ctime, 16); + + spin_lock(&inode->i_lock); + inode->i_generation = zp->z_gen; + inode->i_uid = zp->z_uid; + inode->i_gid = zp->z_gid; + inode->i_nlink = zp->z_links; + inode->i_mode = zp->z_mode; + inode->i_blkbits = SPA_MINBLOCKSHIFT; + dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, + (u_longlong_t *)&inode->i_blocks); + + ZFS_TIME_DECODE(&inode->i_atime, atime); + ZFS_TIME_DECODE(&inode->i_mtime, mtime); + ZFS_TIME_DECODE(&inode->i_ctime, ctime); + + i_size_write(inode, zp->z_size); + spin_unlock(&inode->i_lock); +} + static uint64_t empty_xattr; static uint64_t pad[4]; static zfs_acl_phys_t acl_phys; @@ -1534,6 +1575,7 @@ log: zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); dmu_tx_commit(tx); + zfs_inode_update(zp); return (0); } From 4b3f12ecd5a641b182609d7fe78313d53f6e8976 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 14:46:59 -0800 Subject: [PATCH 32/75] Remove Solaris VFS Hooks The ZFS code is being restructured to act as a library and a stand alone module. This allows us to leverage most of the existing code with minimal modification. It also means we need to drop the Solaris vfs/vnode functions they will be replaced by Linux equivilants and updated to be Linux friendly. --- module/zfs/zfs_ctldir.c | 10 ----- module/zfs/zfs_vfsops.c | 50 --------------------- module/zfs/zfs_znode.c | 99 ----------------------------------------- 3 files changed, 159 deletions(-) diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c index b7dac213f..c2b8b75e6 100644 --- a/module/zfs/zfs_ctldir.c +++ b/module/zfs/zfs_ctldir.c @@ -128,15 +128,6 @@ static vnode_t *zfsctl_mknode_shares(vnode_t *); static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset); static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *); -static gfs_opsvec_t zfsctl_opsvec[] = { - { ".zfs", zfsctl_tops_root, &zfsctl_ops_root }, - { ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir }, - { ".zfs/snapshot/vnode", zfsctl_tops_snapshot, &zfsctl_ops_snapshot }, - { ".zfs/shares", zfsctl_tops_shares, &zfsctl_ops_shares_dir }, - { ".zfs/shares/vnode", zfsctl_tops_shares, &zfsctl_ops_shares }, - { NULL } -}; - /* * Root directory elements. We only have two entries * snapshot and shares. @@ -160,7 +151,6 @@ static gfs_dirent_t zfsctl_root_entries[] = { void zfsctl_init(void) { - VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0); } void diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 4545c20e2..2612dfe3b 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -67,7 +67,6 @@ #ifdef HAVE_ZPL int zfsfstype; -vfsops_t *zfs_vfsops = NULL; static major_t zfs_major; static minor_t zfs_minor; static kmutex_t zfs_dev_mtx; @@ -78,23 +77,6 @@ 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); -static const fs_operation_def_t zfs_vfsops_template[] = { - VFSNAME_MOUNT, { .vfs_mount = zfs_mount }, - VFSNAME_MOUNTROOT, { .vfs_mountroot = zfs_mountroot }, - VFSNAME_UNMOUNT, { .vfs_unmount = zfs_umount }, - VFSNAME_ROOT, { .vfs_root = zfs_root }, - VFSNAME_STATVFS, { .vfs_statvfs = zfs_statvfs }, - VFSNAME_SYNC, { .vfs_sync = zfs_sync }, - VFSNAME_VGET, { .vfs_vget = zfs_vget }, - VFSNAME_FREEVFS, { .vfs_freevfs = zfs_freevfs }, - NULL, NULL -}; - -static const fs_operation_def_t zfs_vfsops_eio_template[] = { - VFSNAME_FREEVFS, { .vfs_freevfs = zfs_freevfs }, - NULL, NULL -}; - /* * We need to keep a count of active fs's. * This is necessary to prevent our module @@ -2065,23 +2047,6 @@ zfs_vfsinit(int fstype, char *name) int error; zfsfstype = fstype; - - /* - * Setup vfsops and vnodeops tables. - */ - error = vfs_setfsops(fstype, zfs_vfsops_template, &zfs_vfsops); - if (error != 0) { - cmn_err(CE_WARN, "zfs: bad vfs ops template"); - } - - error = zfs_create_op_tables(); - if (error) { - zfs_remove_op_tables(); - cmn_err(CE_WARN, "zfs: bad vnode ops template"); - (void) vfs_freevfsops_by_type(zfsfstype); - return (error); - } - mutex_init(&zfs_dev_mtx, NULL, MUTEX_DEFAULT, NULL); /* @@ -2234,18 +2199,3 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) } return (error); } - -#ifdef HAVE_ZPL -static vfsdef_t vfw = { - VFSDEF_VERSION, - MNTTYPE_ZFS, - zfs_vfsinit, - VSW_HASPROTO|VSW_CANRWRO|VSW_CANREMOUNT|VSW_VOLATILEDEV|VSW_STATS| - VSW_XID|VSW_ZMOUNT, - &zfs_mntopts -}; - -struct modlfs zfs_modlfs = { - &mod_fsops, "ZFS filesystem version " SPA_VERSION_STRING, &vfw -}; -#endif /* HAVE_ZPL */ diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 0ae16448f..61eb877aa 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -164,13 +164,6 @@ zfs_znode_init(void) void zfs_znode_fini(void) { - /* - * Cleanup vfs & vnode ops - */ -#ifdef HAVE_ZPL - zfs_remove_op_tables(); -#endif /* HAVE_ZPL */ - /* * Cleanup zcache */ @@ -181,98 +174,6 @@ zfs_znode_fini(void) } #ifdef HAVE_ZPL -struct vnodeops *zfs_dvnodeops; -struct vnodeops *zfs_fvnodeops; -struct vnodeops *zfs_symvnodeops; -struct vnodeops *zfs_xdvnodeops; -struct vnodeops *zfs_evnodeops; -struct vnodeops *zfs_sharevnodeops; - -void -zfs_remove_op_tables() -{ - /* - * Remove vfs ops - */ - ASSERT(zfsfstype); - (void) vfs_freevfsops_by_type(zfsfstype); - zfsfstype = 0; - - /* - * Remove vnode ops - */ - if (zfs_dvnodeops) - vn_freevnodeops(zfs_dvnodeops); - if (zfs_fvnodeops) - vn_freevnodeops(zfs_fvnodeops); - if (zfs_symvnodeops) - vn_freevnodeops(zfs_symvnodeops); - if (zfs_xdvnodeops) - vn_freevnodeops(zfs_xdvnodeops); - if (zfs_evnodeops) - vn_freevnodeops(zfs_evnodeops); - if (zfs_sharevnodeops) - vn_freevnodeops(zfs_sharevnodeops); - - zfs_dvnodeops = NULL; - zfs_fvnodeops = NULL; - zfs_symvnodeops = NULL; - zfs_xdvnodeops = NULL; - zfs_evnodeops = NULL; - zfs_sharevnodeops = NULL; -} - -extern const fs_operation_def_t zfs_dvnodeops_template[]; -extern const fs_operation_def_t zfs_fvnodeops_template[]; -extern const fs_operation_def_t zfs_xdvnodeops_template[]; -extern const fs_operation_def_t zfs_symvnodeops_template[]; -extern const fs_operation_def_t zfs_evnodeops_template[]; -extern const fs_operation_def_t zfs_sharevnodeops_template[]; - -int -zfs_create_op_tables() -{ - int error; - - /* - * zfs_dvnodeops can be set if mod_remove() calls mod_installfs() - * due to a failure to remove the the 2nd modlinkage (zfs_modldrv). - * In this case we just return as the ops vectors are already set up. - */ - if (zfs_dvnodeops) - return (0); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template, - &zfs_dvnodeops); - if (error) - return (error); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template, - &zfs_fvnodeops); - if (error) - return (error); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template, - &zfs_symvnodeops); - if (error) - return (error); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template, - &zfs_xdvnodeops); - if (error) - return (error); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template, - &zfs_evnodeops); - if (error) - return (error); - - error = vn_make_ops(MNTTYPE_ZFS, zfs_sharevnodeops_template, - &zfs_sharevnodeops); - - return (error); -} - int zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) { From c0b3dc7d0797ce2d08df7e07fff15298e957270c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 16:24:57 -0800 Subject: [PATCH 33/75] Remove zfs_major/zfs_minor/zfsfstype Under Linux we don't need to reserve a major or minor number for the filesystem. We can rely on the VFS to handle colisions without this being handled by the lower ZFS layers. Additionally, there is no need to keep a zfsfstype around. We are not limited on Linux by the OpenSolaris infrastructure which needed this. The upper zpl layer can specify the filesystem type. --- module/zfs/zfs_vfsops.c | 107 +--------------------------------------- 1 file changed, 2 insertions(+), 105 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 2612dfe3b..500edfe98 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -66,11 +66,6 @@ #include "zfs_comutil.h" #ifdef HAVE_ZPL -int zfsfstype; -static major_t zfs_major; -static minor_t zfs_minor; -static kmutex_t zfs_dev_mtx; - extern int sys_shutdown; static int zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr); @@ -161,58 +156,6 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) } EXPORT_SYMBOL(zfs_sync); -static int -zfs_create_unique_device(dev_t *dev) -{ - major_t new_major; - - do { - ASSERT3U(zfs_minor, <=, MAXMIN32); - minor_t start = zfs_minor; - do { - mutex_enter(&zfs_dev_mtx); - if (zfs_minor >= MAXMIN32) { - /* - * If we're still using the real major - * keep out of /dev/zfs and /dev/zvol minor - * number space. If we're using a getudev()'ed - * major number, we can use all of its minors. - */ - if (zfs_major == ddi_name_to_major(ZFS_DRIVER)) - zfs_minor = ZFS_MIN_MINOR; - else - zfs_minor = 0; - } else { - zfs_minor++; - } - *dev = makedevice(zfs_major, zfs_minor); - mutex_exit(&zfs_dev_mtx); - } while (vfs_devismounted(*dev) && zfs_minor != start); - if (zfs_minor == start) { - /* - * We are using all ~262,000 minor numbers for the - * current major number. Create a new major number. - */ - if ((new_major = getudev()) == (major_t)-1) { - cmn_err(CE_WARN, - "zfs_mount: Can't get unique major " - "device number."); - return (-1); - } - mutex_enter(&zfs_dev_mtx); - zfs_major = new_major; - zfs_minor = 0; - - mutex_exit(&zfs_dev_mtx); - } else { - break; - } - /* CONSTANTCONDITION */ - } while (1); - - return (0); -} - static void atime_changed_cb(void *arg, uint64_t newval) { @@ -1090,7 +1033,6 @@ zfs_set_fuid_feature(zfsvfs_t *zfsvfs) int zfs_domount(vfs_t *vfsp, char *osname) { - dev_t mount_dev; uint64_t recordsize, fsid_guid; int error = 0; zfsvfs_t *zfsvfs; @@ -1107,18 +1049,10 @@ zfs_domount(vfs_t *vfsp, char *osname) vfsp->vfs_bcount = 0; vfsp->vfs_data = NULL; - if (zfs_create_unique_device(&mount_dev) == -1) { - error = ENODEV; - goto out; - } - ASSERT(vfs_devismounted(mount_dev) == 0); - if ((error = dsl_prop_get_integer(osname, "recordsize", &recordsize, NULL))) goto out; - vfsp->vfs_dev = mount_dev; - vfsp->vfs_fstype = zfsfstype; vfsp->vfs_bsize = recordsize; vfsp->vfs_flag |= VFS_NOTRUNC; vfsp->vfs_data = zfsvfs; @@ -1134,8 +1068,7 @@ zfs_domount(vfs_t *vfsp, char *osname) fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os); ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0); vfsp->vfs_fsid.val[0] = fsid_guid; - vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) | - zfsfstype & 0xFF; + vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8); /* * Set features for file system. @@ -1625,7 +1558,7 @@ zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) /* * We're a zfs filesystem. */ - (void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); + (void) strcpy(statp->f_basetype, MNTTYPE_ZFS); statp->f_flag = vf_to_stf(vfsp->vfs_flag); @@ -2033,47 +1966,13 @@ zfs_freevfs(vfs_t *vfsp) atomic_add_32(&zfs_active_fs_count, -1); } - -/* - * VFS_INIT() initialization. Note that there is no VFS_FINI(), - * so we can't safely do any non-idempotent initialization here. - * Leave that to zfs_init() and zfs_fini(), which are called - * from the module's _init() and _fini() entry points. - */ -/*ARGSUSED*/ -static int -zfs_vfsinit(int fstype, char *name) -{ - int error; - - zfsfstype = fstype; - mutex_init(&zfs_dev_mtx, NULL, MUTEX_DEFAULT, NULL); - - /* - * Unique major number for all zfs mounts. - * If we run out of 32-bit minors, we'll getudev() another major. - */ - zfs_major = ddi_name_to_major(ZFS_DRIVER); - zfs_minor = ZFS_MIN_MINOR; - - return (0); -} #endif /* HAVE_ZPL */ void zfs_init(void) { -#ifdef HAVE_ZPL - /* - * Initialize .zfs directory structures - */ zfsctl_init(); - - /* - * Initialize znode cache, vnode ops, etc... - */ zfs_znode_init(); -#endif /* HAVE_ZPL */ dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); } @@ -2081,10 +1980,8 @@ zfs_init(void) void zfs_fini(void) { -#ifdef HAVE_ZPL zfsctl_fini(); zfs_znode_fini(); -#endif /* HAVE_ZPL */ } #ifdef HAVE_ZPL From 42ab36aa368b09dfec7214cc884b004ee934b2df Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 16:56:49 -0800 Subject: [PATCH 34/75] 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. --- module/zfs/zfs_vfsops.c | 333 ---------------------------------------- 1 file changed, 333 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 500edfe98..58d325f89 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -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); From d7cafa8e3e8973bca6b2ebabafb669508031075e Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 17:00:34 -0800 Subject: [PATCH 35/75] Remove zfs_active_fs_count This variable was used to ensure that the ZFS module is never removed while the filesystem is mounted. Once again the generic Linux VFS handles this case for us so it can be removed. --- module/zfs/zfs_vfsops.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 58d325f89..80cdb21b5 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -68,13 +68,6 @@ #ifdef HAVE_ZPL extern int sys_shutdown; -/* - * We need to keep a count of active fs's. - * This is necessary to prevent our module - * from being unloaded after a umount -f - */ -static uint32_t zfs_active_fs_count = 0; - static char *noatime_cancel[] = { MNTOPT_ATIME, NULL }; static char *atime_cancel[] = { MNTOPT_NOATIME, NULL }; static char *noxattr_cancel[] = { MNTOPT_XATTR, NULL }; @@ -1104,8 +1097,6 @@ out: if (error) { dmu_objset_disown(zfsvfs->z_os, zfsvfs); zfsvfs_free(zfsvfs); - } else { - atomic_add_32(&zfs_active_fs_count, 1); } return (error); @@ -1630,8 +1621,6 @@ zfs_freevfs(vfs_t *vfsp) zfsvfs_t *zfsvfs = vfsp->vfs_data; zfsvfs_free(zfsvfs); - - atomic_add_32(&zfs_active_fs_count, -1); } #endif /* HAVE_ZPL */ From e15c02301489477c9201a80afac46791d20bd070 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 12:56:48 -0800 Subject: [PATCH 36/75] Remove mount options Mount option parsing is still very Linux specific and will be handled above this zfs filesystem layer. Honoring those mount options once set if of course the responsibility of the lower layers. --- module/zfs/zfs_vfsops.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 80cdb21b5..8016766d1 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -68,27 +68,6 @@ #ifdef HAVE_ZPL extern int sys_shutdown; -static char *noatime_cancel[] = { MNTOPT_ATIME, NULL }; -static char *atime_cancel[] = { MNTOPT_NOATIME, NULL }; -static char *noxattr_cancel[] = { MNTOPT_XATTR, NULL }; -static char *xattr_cancel[] = { MNTOPT_NOXATTR, NULL }; - -/* - * MO_DEFAULT is not used since the default value is determined - * by the equivalent property. - */ -static mntopt_t mntopts[] = { - { MNTOPT_NOXATTR, noxattr_cancel, NULL, 0, NULL }, - { MNTOPT_XATTR, xattr_cancel, NULL, 0, NULL }, - { MNTOPT_NOATIME, noatime_cancel, NULL, 0, NULL }, - { MNTOPT_ATIME, atime_cancel, NULL, 0, NULL } -}; - -static mntopts_t zfs_mntopts = { - sizeof (mntopts) / sizeof (mntopt_t), - mntopts -}; - /*ARGSUSED*/ int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) From cb28b3494e88e0e43c43588fccfa6526344b9a64 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 14:15:48 -0800 Subject: [PATCH 37/75] Remove SYNC_ATTR check This flag does not need to be support under Linux. As the comment says it was only there to support fsflush() for old filesystem like UFS. This is not needed under Linux. --- module/zfs/zfs_vfsops.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 8016766d1..c138b6ffe 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -79,15 +79,6 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) if (panicstr) return (0); - /* - * SYNC_ATTR is used by fsflush() to force old filesystems like UFS - * to sync metadata, which they would otherwise cache indefinitely. - * Semantically, the only requirement is that the sync be initiated. - * The DMU syncs out txgs frequently, so there's nothing to do. - */ - if (flag & SYNC_ATTR) - return (0); - if (vfsp != NULL) { /* * Sync a specific filesystem. From acb53769403aa896b022129f1bdb3d845a4d0201 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 5 Jan 2011 16:38:30 -0800 Subject: [PATCH 38/75] Disable Shutdown/Reboot This support has been disable with HAVE_SHUTDOWN. We can support this at some point by adding the needed reboot notifiers. --- module/zfs/zfs_vfsops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index c138b6ffe..a602c5d62 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -66,7 +66,6 @@ #include "zfs_comutil.h" #ifdef HAVE_ZPL -extern int sys_shutdown; /*ARGSUSED*/ int @@ -89,14 +88,19 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) ZFS_ENTER(zfsvfs); dp = dmu_objset_pool(zfsvfs->z_os); +#ifdef HAVE_SHUTDOWN /* * If the system is shutting down, then skip any * filesystems which may exist on a suspended pool. + * + * XXX: This can be implemented using the Linux reboot + * notifiers: {un}register_reboot_notifier(). */ if (sys_shutdown && spa_suspended(dp->dp_spa)) { ZFS_EXIT(zfsvfs); return (0); } +#endif /* HAVE_SHUTDOWN */ if (zfsvfs->z_log != NULL) zil_commit(zfsvfs->z_log, 0); From d5e53f9d06d149fbb62920bb5af766059dc35341 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 14:07:41 -0800 Subject: [PATCH 39/75] Disable zfs_sync during oops/panic Minor update to ensure zfs_sync() is disabled if a kernel oops/panic is triggered. As the comment says 'data integrity is job one'. This change could have been done by defining panicstr to oops_in_progress in the SPL. But I felt it was better to use the native Linux API here since to be clear. --- module/zfs/zfs_vfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index a602c5d62..f5b78aec1 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -75,7 +75,7 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) * Data integrity is job one. We don't want a compromised kernel * writing to the storage pool, so we never sync during panic. */ - if (panicstr) + if (unlikely(oops_in_progress)) return (0); if (vfsp != NULL) { From b516a07b997a8c3006788963f6b6128e505cf56c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 6 Jan 2011 14:53:21 -0800 Subject: [PATCH 40/75] Disable fuid features These features should probably be enabled in the Linux zpl code. For now I'm disabling them until it's clear what needs to be done. --- module/zfs/zfs_vfsops.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index f5b78aec1..14411b8c4 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -978,6 +978,7 @@ zfsvfs_free(zfsvfs_t *zfsvfs) kmem_free(zfsvfs, sizeof (zfsvfs_t)); } +#ifdef HAVE_FUID_FEATURES static void zfs_set_fuid_feature(zfsvfs_t *zfsvfs) { @@ -992,6 +993,7 @@ zfs_set_fuid_feature(zfsvfs_t *zfsvfs) } zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); } +#endif /* HAVE_FUID_FEATURES */ int zfs_domount(vfs_t *vfsp, char *osname) @@ -1033,6 +1035,7 @@ zfs_domount(vfs_t *vfsp, char *osname) vfsp->vfs_fsid.val[0] = fsid_guid; vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8); +#ifdef HAVE_FUID_FEATURES /* * Set features for file system. */ @@ -1046,6 +1049,7 @@ zfs_domount(vfs_t *vfsp, char *osname) vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); } vfs_set_feature(vfsp, VFSFT_ZEROCOPY_SUPPORTED); +#endif /* HAVE_FUID_FEATURES */ if (dmu_objset_is_snapshot(zfsvfs->z_os)) { uint64_t pval; @@ -1677,8 +1681,10 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) zfsvfs->z_version = newvers; +#ifdef HAVE_FUID_FEATURES if (zfsvfs->z_version >= ZPL_VERSION_FUID) zfs_set_fuid_feature(zfsvfs); +#endif /* HAVE_FUID_FEATURES */ return (0); } From bcf308227c9aa51ef9d5a1fe3f2f1342ff2aee94 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:45:24 -0800 Subject: [PATCH 41/75] Remove zfs_ctldir.[ch] This code is used for snapshot and heavily leverages Solaris functionality we do not want to reimplement. These files have been removed, including references to them, and will be replaced by a zfs_snap.c/zpl_snap.c implementation which handles snapshots. --- include/sys/Makefile.am | 1 - include/sys/Makefile.in | 3 - include/sys/zfs_ctldir.h | 73 --- include/sys/zfs_vfsops.h | 31 +- lib/libzpool/Makefile.am | 1 - lib/libzpool/Makefile.in | 1 - module/zfs/Makefile.in | 1 - module/zfs/zfs_ctldir.c | 1342 -------------------------------------- module/zfs/zfs_dir.c | 1 - module/zfs/zfs_ioctl.c | 1 - module/zfs/zfs_vfsops.c | 1 - module/zfs/zfs_vnops.c | 3 +- 12 files changed, 30 insertions(+), 1429 deletions(-) delete mode 100644 include/sys/zfs_ctldir.h delete mode 100644 module/zfs/zfs_ctldir.c diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index a2e8dd01b..63dc24e5b 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -54,7 +54,6 @@ COMMON_H = \ $(top_srcdir)/include/sys/zap_leaf.h \ $(top_srcdir)/include/sys/zfs_acl.h \ $(top_srcdir)/include/sys/zfs_context.h \ - $(top_srcdir)/include/sys/zfs_ctldir.h \ $(top_srcdir)/include/sys/zfs_debug.h \ $(top_srcdir)/include/sys/zfs_dir.h \ $(top_srcdir)/include/sys/zfs_fuid.h \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 4ab3927b0..9243f75ab 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -144,7 +144,6 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/zap_leaf.h \ $(top_srcdir)/include/sys/zfs_acl.h \ $(top_srcdir)/include/sys/zfs_context.h \ - $(top_srcdir)/include/sys/zfs_ctldir.h \ $(top_srcdir)/include/sys/zfs_debug.h \ $(top_srcdir)/include/sys/zfs_dir.h \ $(top_srcdir)/include/sys/zfs_fuid.h \ @@ -240,7 +239,6 @@ am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/zap_leaf.h \ $(top_srcdir)/include/sys/zfs_acl.h \ $(top_srcdir)/include/sys/zfs_context.h \ - $(top_srcdir)/include/sys/zfs_ctldir.h \ $(top_srcdir)/include/sys/zfs_debug.h \ $(top_srcdir)/include/sys/zfs_dir.h \ $(top_srcdir)/include/sys/zfs_fuid.h \ @@ -512,7 +510,6 @@ COMMON_H = \ $(top_srcdir)/include/sys/zap_leaf.h \ $(top_srcdir)/include/sys/zfs_acl.h \ $(top_srcdir)/include/sys/zfs_context.h \ - $(top_srcdir)/include/sys/zfs_ctldir.h \ $(top_srcdir)/include/sys/zfs_debug.h \ $(top_srcdir)/include/sys/zfs_dir.h \ $(top_srcdir)/include/sys/zfs_fuid.h \ diff --git a/include/sys/zfs_ctldir.h b/include/sys/zfs_ctldir.h deleted file mode 100644 index f88ef95fd..000000000 --- a/include/sys/zfs_ctldir.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _ZFS_CTLDIR_H -#define _ZFS_CTLDIR_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZFS_CTLDIR_NAME ".zfs" - -#define zfs_has_ctldir(zdp) \ - ((zdp)->z_id == (zdp)->z_zfsvfs->z_root && \ - ((zdp)->z_zfsvfs->z_ctldir != NULL)) -#define zfs_show_ctldir(zdp) \ - (zfs_has_ctldir(zdp) && \ - ((zdp)->z_zfsvfs->z_show_ctldir)) - -void zfsctl_create(zfsvfs_t *); -void zfsctl_destroy(zfsvfs_t *); -vnode_t *zfsctl_root(znode_t *); -void zfsctl_init(void); -void zfsctl_fini(void); -boolean_t zfsctl_is_node(vnode_t *); - -int zfsctl_rename_snapshot(const char *from, const char *to); -int zfsctl_destroy_snapshot(const char *snapname, int force); -int zfsctl_umount_snapshots(vfs_t *, int, cred_t *); - -int zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, - int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, - int *direntflags, pathname_t *realpnp); - -int zfsctl_make_fid(zfsvfs_t *zfsvfsp, uint64_t object, uint32_t gen, - fid_t *fidp); -int zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp); - -#define ZFSCTL_INO_ROOT 0x1 -#define ZFSCTL_INO_SNAPDIR 0x2 -#define ZFSCTL_INO_SHARES 0x3 - -#ifdef __cplusplus -} -#endif - -#endif /* _ZFS_CTLDIR_H */ diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index ec4097768..34a871587 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -67,7 +67,7 @@ struct zfsvfs { krwlock_t z_teardown_inactive_lock; list_t z_all_znodes; /* all vnodes in the fs */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */ - vnode_t *z_ctldir; /* .zfs directory pointer */ + struct inode *z_ctldir; /* .zfs directory inode */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */ boolean_t z_issnap; /* true if this is a snapshot */ boolean_t z_vscan; /* virus scan on/off */ @@ -83,7 +83,34 @@ struct zfsvfs { sa_attr_type_t *z_attr_table; /* SA attr mapping->id */ #define ZFS_OBJ_MTX_SZ 64 kmutex_t z_hold_mtx[ZFS_OBJ_MTX_SZ]; /* znode hold locks */ -}; +} zfs_sb_t; + +#define ZFS_SUPER_MAGIC 0x2fc12fc1 + + +/* + * Minimal snapshot helpers, the bulk of the Linux snapshot implementation + * lives in the zpl_snap.c file which is part of the zpl source. + */ +#define ZFS_CTLDIR_NAME ".zfs" + +#define zfs_has_ctldir(zdp) \ + ((zdp)->z_id == ZTOZSB(zdp)->z_root && \ + (ZTOZSB(zdp)->z_ctldir != NULL)) +#define zfs_show_ctldir(zdp) \ + (zfs_has_ctldir(zdp) && \ + (ZTOZSB(zdp)->z_show_ctldir)) + +#define ZFSCTL_INO_ROOT 0x1 +#define ZFSCTL_INO_SNAPDIR 0x2 +#define ZFSCTL_INO_SHARES 0x3 + +/* + * Allow a maximum number of links. While ZFS does not internally limit + * this most Linux filesystems do. It's probably a good idea to limit + * this to a large value until it is validated that this is safe. + */ +#define ZFS_LINK_MAX 65536 /* * Normal filesystems (those not under .zfs/snapshot) have a total diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 0c22b8cf7..450f4cca1 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -98,7 +98,6 @@ libzpool_la_LDFLAGS = -pthread EXTRA_DIST = \ $(top_srcdir)/module/zfs/vdev_disk.c \ $(top_srcdir)/module/zfs/zfs_acl.c \ - $(top_srcdir)/module/zfs/zfs_ctldir.c \ $(top_srcdir)/module/zfs/zfs_dir.c \ $(top_srcdir)/module/zfs/zfs_ioctl.c \ $(top_srcdir)/module/zfs/zfs_log.c \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 17f70e6fe..29d312f9d 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -419,7 +419,6 @@ libzpool_la_LDFLAGS = -pthread EXTRA_DIST = \ $(top_srcdir)/module/zfs/vdev_disk.c \ $(top_srcdir)/module/zfs/zfs_acl.c \ - $(top_srcdir)/module/zfs/zfs_ctldir.c \ $(top_srcdir)/module/zfs/zfs_dir.c \ $(top_srcdir)/module/zfs/zfs_ioctl.c \ $(top_srcdir)/module/zfs/zfs_log.c \ diff --git a/module/zfs/Makefile.in b/module/zfs/Makefile.in index 71dbb39fc..7d42481d1 100644 --- a/module/zfs/Makefile.in +++ b/module/zfs/Makefile.in @@ -64,7 +64,6 @@ $(MODULE)-objs += @top_srcdir@/module/zfs/zap_leaf.o $(MODULE)-objs += @top_srcdir@/module/zfs/zap_micro.o $(MODULE)-objs += @top_srcdir@/module/zfs/zfs_acl.o $(MODULE)-objs += @top_srcdir@/module/zfs/zfs_byteswap.o -$(MODULE)-objs += @top_srcdir@/module/zfs/zfs_ctldir.o $(MODULE)-objs += @top_srcdir@/module/zfs/zfs_debug.o $(MODULE)-objs += @top_srcdir@/module/zfs/zfs_dir.o $(MODULE)-objs += @top_srcdir@/module/zfs/zfs_fm.o diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c deleted file mode 100644 index c2b8b75e6..000000000 --- a/module/zfs/zfs_ctldir.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* - * ZFS control directory (a.k.a. ".zfs") - * - * This directory provides a common location for all ZFS meta-objects. - * Currently, this is only the 'snapshot' directory, but this may expand in the - * future. The elements are built using the GFS primitives, as the hierarchy - * does not actually exist on disk. - * - * For 'snapshot', we don't want to have all snapshots always mounted, because - * this would take up a huge amount of space in /etc/mtab. We have three - * types of objects: - * - * ctldir ------> snapshotdir -------> snapshot - * | - * | - * V - * mounted fs - * - * The 'snapshot' node contains just enough information to lookup '..' and act - * as a mountpoint for the snapshot. Whenever we lookup a specific snapshot, we - * perform an automount of the underlying filesystem and return the - * corresponding vnode. - * - * All mounts are handled automatically by the kernel, but unmounts are - * (currently) handled from user land. The main reason is that there is no - * reliable way to auto-unmount the filesystem when it's "no longer in use". - * When the user unmounts a filesystem, we call zfsctl_unmount(), which - * unmounts any snapshots within the snapshot directory. - * - * The '.zfs', '.zfs/snapshot', and all directories created under - * '.zfs/snapshot' (ie: '.zfs/snapshot/') are all GFS nodes and - * share the same vfs_t as the head filesystem (what '.zfs' lives under). - * - * File systems mounted ontop of the GFS nodes '.zfs/snapshot/' - * (ie: snapshots) are ZFS nodes and have their own unique vfs_t. - * However, vnodes within these mounted on file systems have their v_vfsp - * fields set to the head filesystem to make NFS happy (see - * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t - * so that it cannot be freed until all snapshots have been unmounted. - */ - -#ifdef HAVE_ZPL - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zfs_namecheck.h" - -typedef struct zfsctl_node { - gfs_dir_t zc_gfs_private; - uint64_t zc_id; - timestruc_t zc_cmtime; /* ctime and mtime, always the same */ -} zfsctl_node_t; - -typedef struct zfsctl_snapdir { - zfsctl_node_t sd_node; - kmutex_t sd_lock; - avl_tree_t sd_snaps; -} zfsctl_snapdir_t; - -typedef struct { - char *se_name; - vnode_t *se_root; - avl_node_t se_node; -} zfs_snapentry_t; - -static int -snapentry_compare(const void *a, const void *b) -{ - const zfs_snapentry_t *sa = a; - const zfs_snapentry_t *sb = b; - int ret = strcmp(sa->se_name, sb->se_name); - - if (ret < 0) - return (-1); - else if (ret > 0) - return (1); - else - return (0); -} - -vnodeops_t *zfsctl_ops_root; -vnodeops_t *zfsctl_ops_snapdir; -vnodeops_t *zfsctl_ops_snapshot; -vnodeops_t *zfsctl_ops_shares; -vnodeops_t *zfsctl_ops_shares_dir; - -static const fs_operation_def_t zfsctl_tops_root[]; -static const fs_operation_def_t zfsctl_tops_snapdir[]; -static const fs_operation_def_t zfsctl_tops_snapshot[]; -static const fs_operation_def_t zfsctl_tops_shares[]; - -static vnode_t *zfsctl_mknode_snapdir(vnode_t *); -static vnode_t *zfsctl_mknode_shares(vnode_t *); -static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset); -static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *); - -/* - * Root directory elements. We only have two entries - * snapshot and shares. - */ -static gfs_dirent_t zfsctl_root_entries[] = { - { "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE }, - { "shares", zfsctl_mknode_shares, GFS_CACHE_VNODE }, - { NULL } -}; - -/* include . and .. in the calculation */ -#define NROOT_ENTRIES ((sizeof (zfsctl_root_entries) / \ - sizeof (gfs_dirent_t)) + 1) - - -/* - * Initialize the various GFS pieces we'll need to create and manipulate .zfs - * directories. This is called from the ZFS init routine, and initializes the - * vnode ops vectors that we'll be using. - */ -void -zfsctl_init(void) -{ -} - -void -zfsctl_fini(void) -{ - /* - * Remove vfsctl vnode ops - */ - if (zfsctl_ops_root) - vn_freevnodeops(zfsctl_ops_root); - if (zfsctl_ops_snapdir) - vn_freevnodeops(zfsctl_ops_snapdir); - if (zfsctl_ops_snapshot) - vn_freevnodeops(zfsctl_ops_snapshot); - if (zfsctl_ops_shares) - vn_freevnodeops(zfsctl_ops_shares); - if (zfsctl_ops_shares_dir) - vn_freevnodeops(zfsctl_ops_shares_dir); - - zfsctl_ops_root = NULL; - zfsctl_ops_snapdir = NULL; - zfsctl_ops_snapshot = NULL; - zfsctl_ops_shares = NULL; - zfsctl_ops_shares_dir = NULL; -} - -boolean_t -zfsctl_is_node(vnode_t *vp) -{ - return (vn_matchops(vp, zfsctl_ops_root) || - vn_matchops(vp, zfsctl_ops_snapdir) || - vn_matchops(vp, zfsctl_ops_snapshot) || - vn_matchops(vp, zfsctl_ops_shares) || - vn_matchops(vp, zfsctl_ops_shares_dir)); - -} - -/* - * Return the inode number associated with the 'snapshot' or - * 'shares' directory. - */ -/* ARGSUSED */ -static ino64_t -zfsctl_root_inode_cb(vnode_t *vp, int index) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - - ASSERT(index <= 2); - - if (index == 0) - return (ZFSCTL_INO_SNAPDIR); - - return (zfsvfs->z_shares_dir); -} - -/* - * Create the '.zfs' directory. This directory is cached as part of the VFS - * structure. This results in a hold on the vfs_t. The code in zfs_umount() - * therefore checks against a vfs_count of 2 instead of 1. This reference - * is removed when the ctldir is destroyed in the unmount. - */ -void -zfsctl_create(zfsvfs_t *zfsvfs) -{ - vnode_t *vp, *rvp; - zfsctl_node_t *zcp; - uint64_t crtime[2]; - - ASSERT(zfsvfs->z_ctldir == NULL); - - vp = gfs_root_create(sizeof (zfsctl_node_t), zfsvfs->z_vfs, - zfsctl_ops_root, ZFSCTL_INO_ROOT, zfsctl_root_entries, - zfsctl_root_inode_cb, MAXNAMELEN, NULL, NULL); - zcp = vp->v_data; - zcp->zc_id = ZFSCTL_INO_ROOT; - - VERIFY(VFS_ROOT(zfsvfs->z_vfs, &rvp) == 0); - VERIFY(0 == sa_lookup(VTOZ(rvp)->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs), - &crtime, sizeof (crtime))); - ZFS_TIME_DECODE(&zcp->zc_cmtime, crtime); - VN_RELE(rvp); - - /* - * We're only faking the fact that we have a root of a filesystem for - * the sake of the GFS interfaces. Undo the flag manipulation it did - * for us. - */ - vp->v_flag &= ~(VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT); - - zfsvfs->z_ctldir = vp; -} - -/* - * Destroy the '.zfs' directory. Only called when the filesystem is unmounted. - * There might still be more references if we were force unmounted, but only - * new zfs_inactive() calls can occur and they don't reference .zfs - */ -void -zfsctl_destroy(zfsvfs_t *zfsvfs) -{ - VN_RELE(zfsvfs->z_ctldir); - zfsvfs->z_ctldir = NULL; -} - -/* - * Given a root znode, retrieve the associated .zfs directory. - * Add a hold to the vnode and return it. - */ -vnode_t * -zfsctl_root(znode_t *zp) -{ - ASSERT(zfs_has_ctldir(zp)); - VN_HOLD(zp->z_zfsvfs->z_ctldir); - return (zp->z_zfsvfs->z_ctldir); -} - -/* - * Common open routine. Disallow any write access. - */ -/* ARGSUSED */ -static int -zfsctl_common_open(vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct) -{ - if (flags & FWRITE) - return (EACCES); - - return (0); -} - -/* - * Common close routine. Nothing to do here. - */ -/* ARGSUSED */ -static int -zfsctl_common_close(vnode_t *vpp, int flags, int count, offset_t off, - cred_t *cr, caller_context_t *ct) -{ - return (0); -} - -/* - * Common access routine. Disallow writes. - */ -/* ARGSUSED */ -static int -zfsctl_common_access(vnode_t *vp, int mode, int flags, cred_t *cr, - caller_context_t *ct) -{ - if (flags & V_ACE_MASK) { - if (mode & ACE_ALL_WRITE_PERMS) - return (EACCES); - } else { - if (mode & VWRITE) - return (EACCES); - } - - return (0); -} - -/* - * Common getattr function. Fill in basic information. - */ -static void -zfsctl_common_getattr(vnode_t *vp, vattr_t *vap) -{ - timestruc_t now; - - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_rdev = 0; - /* - * We are a purely virtual object, so we have no - * blocksize or allocated blocks. - */ - vap->va_blksize = 0; - vap->va_nblocks = 0; - vap->va_seq = 0; - vap->va_fsid = vp->v_vfsp->vfs_dev; - vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | - S_IROTH | S_IXOTH; - vap->va_type = VDIR; - /* - * We live in the now (for atime). - */ - gethrestime(&now); - vap->va_atime = now; -} - -/*ARGSUSED*/ -static int -zfsctl_common_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - zfsctl_node_t *zcp = vp->v_data; - uint64_t object = zcp->zc_id; - zfid_short_t *zfid; - int i; - - ZFS_ENTER(zfsvfs); - - if (fidp->fid_len < SHORT_FID_LEN) { - fidp->fid_len = SHORT_FID_LEN; - ZFS_EXIT(zfsvfs); - return (ENOSPC); - } - - zfid = (zfid_short_t *)fidp; - - zfid->zf_len = SHORT_FID_LEN; - - for (i = 0; i < sizeof (zfid->zf_object); i++) - zfid->zf_object[i] = (uint8_t)(object >> (8 * i)); - - /* .zfs znodes always have a generation number of 0 */ - for (i = 0; i < sizeof (zfid->zf_gen); i++) - zfid->zf_gen[i] = 0; - - ZFS_EXIT(zfsvfs); - return (0); -} - - -/*ARGSUSED*/ -static int -zfsctl_shares_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - znode_t *dzp; - int error; - - ZFS_ENTER(zfsvfs); - - if (zfsvfs->z_shares_dir == 0) { - ZFS_EXIT(zfsvfs); - return (ENOTSUP); - } - - if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) { - error = VOP_FID(ZTOV(dzp), fidp, ct); - VN_RELE(ZTOV(dzp)); - } - - ZFS_EXIT(zfsvfs); - return (error); -} -/* - * .zfs inode namespace - * - * We need to generate unique inode numbers for all files and directories - * within the .zfs pseudo-filesystem. We use the following scheme: - * - * ENTRY ZFSCTL_INODE - * .zfs 1 - * .zfs/snapshot 2 - * .zfs/snapshot/ objectid(snap) - */ - -#define ZFSCTL_INO_SNAP(id) (id) - -/* - * Get root directory attributes. - */ -/* ARGSUSED */ -static int -zfsctl_root_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - zfsctl_node_t *zcp = vp->v_data; - - ZFS_ENTER(zfsvfs); - vap->va_nodeid = ZFSCTL_INO_ROOT; - vap->va_nlink = vap->va_size = NROOT_ENTRIES; - vap->va_mtime = vap->va_ctime = zcp->zc_cmtime; - - zfsctl_common_getattr(vp, vap); - ZFS_EXIT(zfsvfs); - - return (0); -} - -/* - * Special case the handling of "..". - */ -/* ARGSUSED */ -int -zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, - int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, - int *direntflags, pathname_t *realpnp) -{ - zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; - int err; - - /* - * No extended attributes allowed under .zfs - */ - if (flags & LOOKUP_XATTR) - return (EINVAL); - - ZFS_ENTER(zfsvfs); - - if (strcmp(nm, "..") == 0) { - err = VFS_ROOT(dvp->v_vfsp, vpp); - } else { - err = gfs_vop_lookup(dvp, nm, vpp, pnp, flags, rdir, - cr, ct, direntflags, realpnp); - } - - ZFS_EXIT(zfsvfs); - - return (err); -} - -static int -zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, - caller_context_t *ct) -{ - /* - * We only care about ACL_ENABLED so that libsec can - * display ACL correctly and not default to POSIX draft. - */ - if (cmd == _PC_ACL_ENABLED) { - *valp = _ACL_ACE_ENABLED; - return (0); - } - - return (fs_pathconf(vp, cmd, valp, cr, ct)); -} - -static const fs_operation_def_t zfsctl_tops_root[] = { - { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, - { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, - { VOPNAME_IOCTL, { .error = fs_inval } }, - { VOPNAME_GETATTR, { .vop_getattr = zfsctl_root_getattr } }, - { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, - { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } }, - { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_root_lookup } }, - { VOPNAME_SEEK, { .vop_seek = fs_seek } }, - { VOPNAME_INACTIVE, { .vop_inactive = gfs_vop_inactive } }, - { VOPNAME_PATHCONF, { .vop_pathconf = zfsctl_pathconf } }, - { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, - { NULL } -}; - -static int -zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname) -{ - objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os; - - if (snapshot_namecheck(name, NULL, NULL) != 0) - return (EILSEQ); - dmu_objset_name(os, zname); - if (strlen(zname) + 1 + strlen(name) >= len) - return (ENAMETOOLONG); - (void) strcat(zname, "@"); - (void) strcat(zname, name); - return (0); -} - -static int -zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr) -{ - vnode_t *svp = sep->se_root; - int error; - - ASSERT(vn_ismntpt(svp)); - - /* this will be dropped by dounmount() */ - if ((error = vn_vfswlock(svp)) != 0) - return (error); - - VN_HOLD(svp); - error = dounmount(vn_mountedvfs(svp), fflags, cr); - if (error) { - VN_RELE(svp); - return (error); - } - - /* - * We can't use VN_RELE(), as that will try to invoke - * zfsctl_snapdir_inactive(), which would cause us to destroy - * the sd_lock mutex held by our caller. - */ - ASSERT(svp->v_count == 1); - gfs_vop_inactive(svp, cr, NULL); - - kmem_free(sep->se_name, strlen(sep->se_name) + 1); - kmem_free(sep, sizeof (zfs_snapentry_t)); - - return (0); -} - -static void -zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) -{ - avl_index_t where; - vfs_t *vfsp; - refstr_t *pathref; - char newpath[MAXNAMELEN]; - char *tail; - - ASSERT(MUTEX_HELD(&sdp->sd_lock)); - ASSERT(sep != NULL); - - vfsp = vn_mountedvfs(sep->se_root); - ASSERT(vfsp != NULL); - - vfs_lock_wait(vfsp); - - /* - * Change the name in the AVL tree. - */ - avl_remove(&sdp->sd_snaps, sep); - kmem_free(sep->se_name, strlen(sep->se_name) + 1); - sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP); - (void) strcpy(sep->se_name, nm); - VERIFY(avl_find(&sdp->sd_snaps, sep, &where) == NULL); - avl_insert(&sdp->sd_snaps, sep, where); - - /* - * Change the current mountpoint info: - * - update the tail of the mntpoint path - * - update the tail of the resource path - */ - pathref = vfs_getmntpoint(vfsp); - (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath)); - VERIFY((tail = strrchr(newpath, '/')) != NULL); - *(tail+1) = '\0'; - ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); - (void) strcat(newpath, nm); - refstr_rele(pathref); - vfs_setmntpoint(vfsp, newpath, 0); - - pathref = vfs_getresource(vfsp); - (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath)); - VERIFY((tail = strrchr(newpath, '@')) != NULL); - *(tail+1) = '\0'; - ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); - (void) strcat(newpath, nm); - refstr_rele(pathref); - vfs_setresource(vfsp, newpath, 0); - - vfs_unlock(vfsp); -} - -/*ARGSUSED*/ -static int -zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, - cred_t *cr, caller_context_t *ct, int flags) -{ - zfsctl_snapdir_t *sdp = sdvp->v_data; - zfs_snapentry_t search, *sep; - zfsvfs_t *zfsvfs; - avl_index_t where; - char from[MAXNAMELEN], to[MAXNAMELEN]; - char real[MAXNAMELEN]; - int err; - - zfsvfs = sdvp->v_vfsp->vfs_data; - ZFS_ENTER(zfsvfs); - - if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { - err = dmu_snapshot_realname(zfsvfs->z_os, snm, real, - MAXNAMELEN, NULL); - if (err == 0) { - snm = real; - } else if (err != ENOTSUP) { - ZFS_EXIT(zfsvfs); - return (err); - } - } - - ZFS_EXIT(zfsvfs); - - err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from); - if (!err) - err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to); - if (!err) - err = zfs_secpolicy_rename_perms(from, to, cr); - if (err) - return (err); - - /* - * Cannot move snapshots out of the snapdir. - */ - if (sdvp != tdvp) - return (EINVAL); - - if (strcmp(snm, tnm) == 0) - return (0); - - mutex_enter(&sdp->sd_lock); - - search.se_name = (char *)snm; - if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) { - mutex_exit(&sdp->sd_lock); - return (ENOENT); - } - - err = dmu_objset_rename(from, to, B_FALSE); - if (err == 0) - zfsctl_rename_snap(sdp, sep, tnm); - - mutex_exit(&sdp->sd_lock); - - return (err); -} - -/* ARGSUSED */ -static int -zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, - caller_context_t *ct, int flags) -{ - zfsctl_snapdir_t *sdp = dvp->v_data; - zfs_snapentry_t *sep; - zfs_snapentry_t search; - zfsvfs_t *zfsvfs; - char snapname[MAXNAMELEN]; - char real[MAXNAMELEN]; - int err; - - zfsvfs = dvp->v_vfsp->vfs_data; - ZFS_ENTER(zfsvfs); - - if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { - - err = dmu_snapshot_realname(zfsvfs->z_os, name, real, - MAXNAMELEN, NULL); - if (err == 0) { - name = real; - } else if (err != ENOTSUP) { - ZFS_EXIT(zfsvfs); - return (err); - } - } - - ZFS_EXIT(zfsvfs); - - err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname); - if (!err) - err = zfs_secpolicy_destroy_perms(snapname, cr); - if (err) - return (err); - - mutex_enter(&sdp->sd_lock); - - search.se_name = name; - sep = avl_find(&sdp->sd_snaps, &search, NULL); - if (sep) { - avl_remove(&sdp->sd_snaps, sep); - err = zfsctl_unmount_snap(sep, MS_FORCE, cr); - if (err) - avl_add(&sdp->sd_snaps, sep); - else - err = dmu_objset_destroy(snapname, B_FALSE); - } else { - err = ENOENT; - } - - mutex_exit(&sdp->sd_lock); - - return (err); -} - -/* - * This creates a snapshot under '.zfs/snapshot'. - */ -/* ARGSUSED */ -static int -zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, - cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp) -{ - zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; - char name[MAXNAMELEN]; - int err; - static enum symfollow follow = NO_FOLLOW; - static enum uio_seg seg = UIO_SYSSPACE; - - if (snapshot_namecheck(dirname, NULL, NULL) != 0) - return (EILSEQ); - - dmu_objset_name(zfsvfs->z_os, name); - - *vpp = NULL; - - err = zfs_secpolicy_snapshot_perms(name, cr); - if (err) - return (err); - - if (err == 0) { - err = dmu_objset_snapshot(name, dirname, NULL, NULL, - B_FALSE, B_FALSE, -1); - if (err) - return (err); - err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp); - } - - return (err); -} - -/* - * Lookup entry point for the 'snapshot' directory. Try to open the - * snapshot if it exist, creating the pseudo filesystem vnode as necessary. - * Perform a mount of the associated dataset on top of the vnode. - */ -/* ARGSUSED */ -static int -zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, - int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, - int *direntflags, pathname_t *realpnp) -{ - zfsctl_snapdir_t *sdp = dvp->v_data; - objset_t *snap; - char snapname[MAXNAMELEN]; - char real[MAXNAMELEN]; - char *mountpoint; - zfs_snapentry_t *sep, search; - struct mounta margs; - vfs_t *vfsp; - size_t mountpoint_len; - avl_index_t where; - zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; - int err; - - /* - * No extended attributes allowed under .zfs - */ - if (flags & LOOKUP_XATTR) - return (EINVAL); - - ASSERT(dvp->v_type == VDIR); - - /* - * If we get a recursive call, that means we got called - * from the domount() code while it was trying to look up the - * spec (which looks like a local path for zfs). We need to - * add some flag to domount() to tell it not to do this lookup. - */ - if (MUTEX_HELD(&sdp->sd_lock)) - return (ENOENT); - - ZFS_ENTER(zfsvfs); - - if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) { - ZFS_EXIT(zfsvfs); - return (0); - } - - if (flags & FIGNORECASE) { - boolean_t conflict = B_FALSE; - - err = dmu_snapshot_realname(zfsvfs->z_os, nm, real, - MAXNAMELEN, &conflict); - if (err == 0) { - nm = real; - } else if (err != ENOTSUP) { - ZFS_EXIT(zfsvfs); - return (err); - } - if (realpnp) - (void) strlcpy(realpnp->pn_buf, nm, - realpnp->pn_bufsize); - if (conflict && direntflags) - *direntflags = ED_CASE_CONFLICT; - } - - mutex_enter(&sdp->sd_lock); - search.se_name = (char *)nm; - if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) { - *vpp = sep->se_root; - VN_HOLD(*vpp); - err = traverse(vpp); - if (err) { - VN_RELE(*vpp); - *vpp = NULL; - } else if (*vpp == sep->se_root) { - /* - * The snapshot was unmounted behind our backs, - * try to remount it. - */ - goto domount; - } else { - /* - * VROOT was set during the traverse call. We need - * to clear it since we're pretending to be part - * of our parent's vfs. - */ - (*vpp)->v_flag &= ~VROOT; - } - mutex_exit(&sdp->sd_lock); - ZFS_EXIT(zfsvfs); - return (err); - } - - /* - * The requested snapshot is not currently mounted, look it up. - */ - err = zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname); - if (err) { - mutex_exit(&sdp->sd_lock); - ZFS_EXIT(zfsvfs); - /* - * handle "ls *" or "?" in a graceful manner, - * forcing EILSEQ to ENOENT. - * Since shell ultimately passes "*" or "?" as name to lookup - */ - return (err == EILSEQ ? ENOENT : err); - } - if (dmu_objset_hold(snapname, FTAG, &snap) != 0) { - mutex_exit(&sdp->sd_lock); - ZFS_EXIT(zfsvfs); - return (ENOENT); - } - - sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP); - sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP); - (void) strcpy(sep->se_name, nm); - *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap)); - avl_insert(&sdp->sd_snaps, sep, where); - - dmu_objset_rele(snap, FTAG); -domount: - mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) + - strlen("/.zfs/snapshot/") + strlen(nm) + 1; - mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP); - (void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s", - refstr_value(dvp->v_vfsp->vfs_mntpt), nm); - - margs.spec = snapname; - margs.dir = mountpoint; - margs.flags = MS_SYSSPACE | MS_NOMNTTAB; - margs.fstype = "zfs"; - margs.dataptr = NULL; - margs.datalen = 0; - margs.optptr = NULL; - margs.optlen = 0; - - err = domount("zfs", &margs, *vpp, kcred, &vfsp); - kmem_free(mountpoint, mountpoint_len); - - if (err == 0) { - /* - * Return the mounted root rather than the covered mount point. - * Takes the GFS vnode at .zfs/snapshot/ and returns - * the ZFS vnode mounted on top of the GFS node. This ZFS - * vnode is the root of the newly created vfsp. - */ - VFS_RELE(vfsp); - err = traverse(vpp); - } - - if (err == 0) { - /* - * Fix up the root vnode mounted on .zfs/snapshot/. - * - * This is where we lie about our v_vfsp in order to - * make .zfs/snapshot/ accessible over NFS - * without requiring manual mounts of . - */ - ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs); - VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs; - (*vpp)->v_vfsp = zfsvfs->z_vfs; - (*vpp)->v_flag &= ~VROOT; - } - mutex_exit(&sdp->sd_lock); - ZFS_EXIT(zfsvfs); - - /* - * If we had an error, drop our hold on the vnode and - * zfsctl_snapshot_inactive() will clean up. - */ - if (err) { - VN_RELE(*vpp); - *vpp = NULL; - } - return (err); -} - -/* ARGSUSED */ -static int -zfsctl_shares_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, - int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, - int *direntflags, pathname_t *realpnp) -{ - zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; - znode_t *dzp; - int error; - - ZFS_ENTER(zfsvfs); - - if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) { - ZFS_EXIT(zfsvfs); - return (0); - } - - if (zfsvfs->z_shares_dir == 0) { - ZFS_EXIT(zfsvfs); - return (ENOTSUP); - } - if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) - error = VOP_LOOKUP(ZTOV(dzp), nm, vpp, pnp, - flags, rdir, cr, ct, direntflags, realpnp); - - VN_RELE(ZTOV(dzp)); - ZFS_EXIT(zfsvfs); - - return (error); -} - -/* ARGSUSED */ -static int -zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp, - offset_t *offp, offset_t *nextp, void *data, int flags) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - char snapname[MAXNAMELEN]; - uint64_t id, cookie; - boolean_t case_conflict; - int error; - - ZFS_ENTER(zfsvfs); - - cookie = *offp; - error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id, - &cookie, &case_conflict); - if (error) { - ZFS_EXIT(zfsvfs); - if (error == ENOENT) { - *eofp = 1; - return (0); - } - return (error); - } - - if (flags & V_RDDIR_ENTFLAGS) { - edirent_t *eodp = dp; - - (void) strcpy(eodp->ed_name, snapname); - eodp->ed_ino = ZFSCTL_INO_SNAP(id); - eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0; - } else { - struct dirent64 *odp = dp; - - (void) strcpy(odp->d_name, snapname); - odp->d_ino = ZFSCTL_INO_SNAP(id); - } - *nextp = cookie; - - ZFS_EXIT(zfsvfs); - - return (0); -} - -/* ARGSUSED */ -static int -zfsctl_shares_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp, - caller_context_t *ct, int flags) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - znode_t *dzp; - int error; - - ZFS_ENTER(zfsvfs); - - if (zfsvfs->z_shares_dir == 0) { - ZFS_EXIT(zfsvfs); - return (ENOTSUP); - } - if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) { - error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp, ct, flags); - VN_RELE(ZTOV(dzp)); - } else { - *eofp = 1; - error = ENOENT; - } - - ZFS_EXIT(zfsvfs); - return (error); -} - -/* - * pvp is the '.zfs' directory (zfsctl_node_t). - * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t). - * - * This function is the callback to create a GFS vnode for '.zfs/snapshot' - * when a lookup is performed on .zfs for "snapshot". - */ -vnode_t * -zfsctl_mknode_snapdir(vnode_t *pvp) -{ - vnode_t *vp; - zfsctl_snapdir_t *sdp; - - vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp, - zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN, - zfsctl_snapdir_readdir_cb, NULL); - sdp = vp->v_data; - sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR; - sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime; - mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL); - avl_create(&sdp->sd_snaps, snapentry_compare, - sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node)); - return (vp); -} - -vnode_t * -zfsctl_mknode_shares(vnode_t *pvp) -{ - vnode_t *vp; - zfsctl_node_t *sdp; - - vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, - zfsctl_ops_shares, NULL, NULL, MAXNAMELEN, - NULL, NULL); - sdp = vp->v_data; - sdp->zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime; - return (vp); - -} - -/* ARGSUSED */ -static int -zfsctl_shares_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - znode_t *dzp; - int error; - - ZFS_ENTER(zfsvfs); - if (zfsvfs->z_shares_dir == 0) { - ZFS_EXIT(zfsvfs); - return (ENOTSUP); - } - if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) { - error = VOP_GETATTR(ZTOV(dzp), vap, flags, cr, ct); - VN_RELE(ZTOV(dzp)); - } - ZFS_EXIT(zfsvfs); - return (error); - - -} - -/* ARGSUSED */ -static int -zfsctl_snapdir_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct) -{ - zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; - zfsctl_snapdir_t *sdp = vp->v_data; - - ZFS_ENTER(zfsvfs); - zfsctl_common_getattr(vp, vap); - vap->va_nodeid = gfs_file_inode(vp); - vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2; - vap->va_ctime = vap->va_mtime = dmu_objset_snap_cmtime(zfsvfs->z_os); - ZFS_EXIT(zfsvfs); - - return (0); -} - -/* ARGSUSED */ -static void -zfsctl_snapdir_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) -{ - zfsctl_snapdir_t *sdp = vp->v_data; - void *private; - - private = gfs_dir_inactive(vp); - if (private != NULL) { - ASSERT(avl_numnodes(&sdp->sd_snaps) == 0); - mutex_destroy(&sdp->sd_lock); - avl_destroy(&sdp->sd_snaps); - kmem_free(private, sizeof (zfsctl_snapdir_t)); - } -} - -static const fs_operation_def_t zfsctl_tops_snapdir[] = { - { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, - { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, - { VOPNAME_IOCTL, { .error = fs_inval } }, - { VOPNAME_GETATTR, { .vop_getattr = zfsctl_snapdir_getattr } }, - { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, - { VOPNAME_RENAME, { .vop_rename = zfsctl_snapdir_rename } }, - { VOPNAME_RMDIR, { .vop_rmdir = zfsctl_snapdir_remove } }, - { VOPNAME_MKDIR, { .vop_mkdir = zfsctl_snapdir_mkdir } }, - { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } }, - { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_snapdir_lookup } }, - { VOPNAME_SEEK, { .vop_seek = fs_seek } }, - { VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapdir_inactive } }, - { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, - { NULL } -}; - -static const fs_operation_def_t zfsctl_tops_shares[] = { - { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, - { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, - { VOPNAME_IOCTL, { .error = fs_inval } }, - { VOPNAME_GETATTR, { .vop_getattr = zfsctl_shares_getattr } }, - { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, - { VOPNAME_READDIR, { .vop_readdir = zfsctl_shares_readdir } }, - { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_shares_lookup } }, - { VOPNAME_SEEK, { .vop_seek = fs_seek } }, - { VOPNAME_INACTIVE, { .vop_inactive = gfs_vop_inactive } }, - { VOPNAME_FID, { .vop_fid = zfsctl_shares_fid } }, - { NULL } -}; - -/* - * pvp is the GFS vnode '.zfs/snapshot'. - * - * This creates a GFS node under '.zfs/snapshot' representing each - * snapshot. This newly created GFS node is what we mount snapshot - * vfs_t's ontop of. - */ -static vnode_t * -zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset) -{ - vnode_t *vp; - zfsctl_node_t *zcp; - - vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, - zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL); - zcp = vp->v_data; - zcp->zc_id = objset; - - return (vp); -} - -static void -zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) -{ - zfsctl_snapdir_t *sdp; - zfs_snapentry_t *sep, *next; - vnode_t *dvp; - - VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0); - sdp = dvp->v_data; - - mutex_enter(&sdp->sd_lock); - - if (vp->v_count > 1) { - mutex_exit(&sdp->sd_lock); - return; - } - ASSERT(!vn_ismntpt(vp)); - - sep = avl_first(&sdp->sd_snaps); - while (sep != NULL) { - next = AVL_NEXT(&sdp->sd_snaps, sep); - - if (sep->se_root == vp) { - avl_remove(&sdp->sd_snaps, sep); - kmem_free(sep->se_name, strlen(sep->se_name) + 1); - kmem_free(sep, sizeof (zfs_snapentry_t)); - break; - } - sep = next; - } - ASSERT(sep != NULL); - - mutex_exit(&sdp->sd_lock); - VN_RELE(dvp); - - /* - * Dispose of the vnode for the snapshot mount point. - * This is safe to do because once this entry has been removed - * from the AVL tree, it can't be found again, so cannot become - * "active". If we lookup the same name again we will end up - * creating a new vnode. - */ - gfs_vop_inactive(vp, cr, ct); -} - - -/* - * These VP's should never see the light of day. They should always - * be covered. - */ -static const fs_operation_def_t zfsctl_tops_snapshot[] = { - VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapshot_inactive }, - NULL, NULL -}; - -int -zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp) -{ - zfsvfs_t *zfsvfs = vfsp->vfs_data; - vnode_t *dvp, *vp; - zfsctl_snapdir_t *sdp; - zfsctl_node_t *zcp; - zfs_snapentry_t *sep; - int error; - - ASSERT(zfsvfs->z_ctldir != NULL); - error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, - NULL, 0, NULL, kcred, NULL, NULL, NULL); - if (error != 0) - return (error); - sdp = dvp->v_data; - - mutex_enter(&sdp->sd_lock); - sep = avl_first(&sdp->sd_snaps); - while (sep != NULL) { - vp = sep->se_root; - zcp = vp->v_data; - if (zcp->zc_id == objsetid) - break; - - sep = AVL_NEXT(&sdp->sd_snaps, sep); - } - - if (sep != NULL) { - VN_HOLD(vp); - /* - * Return the mounted root rather than the covered mount point. - * Takes the GFS vnode at .zfs/snapshot/ - * and returns the ZFS vnode mounted on top of the GFS node. - * This ZFS vnode is the root of the vfs for objset 'objsetid'. - */ - error = traverse(&vp); - if (error == 0) { - if (vp == sep->se_root) - error = EINVAL; - else - *zfsvfsp = VTOZ(vp)->z_zfsvfs; - } - mutex_exit(&sdp->sd_lock); - VN_RELE(vp); - } else { - error = EINVAL; - mutex_exit(&sdp->sd_lock); - } - - VN_RELE(dvp); - - return (error); -} - -/* - * Unmount any snapshots for the given filesystem. This is called from - * zfs_umount() - if we have a ctldir, then go through and unmount all the - * snapshots. - */ -int -zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr) -{ - zfsvfs_t *zfsvfs = vfsp->vfs_data; - vnode_t *dvp; - zfsctl_snapdir_t *sdp; - zfs_snapentry_t *sep, *next; - int error; - - ASSERT(zfsvfs->z_ctldir != NULL); - error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, - NULL, 0, NULL, cr, NULL, NULL, NULL); - if (error != 0) - return (error); - sdp = dvp->v_data; - - mutex_enter(&sdp->sd_lock); - - sep = avl_first(&sdp->sd_snaps); - while (sep != NULL) { - next = AVL_NEXT(&sdp->sd_snaps, sep); - - /* - * If this snapshot is not mounted, then it must - * have just been unmounted by somebody else, and - * will be cleaned up by zfsctl_snapdir_inactive(). - */ - if (vn_ismntpt(sep->se_root)) { - avl_remove(&sdp->sd_snaps, sep); - error = zfsctl_unmount_snap(sep, fflags, cr); - if (error) { - avl_add(&sdp->sd_snaps, sep); - break; - } - } - sep = next; - } - - mutex_exit(&sdp->sd_lock); - VN_RELE(dvp); - - return (error); -} -#endif /* HAVE_ZPL */ diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c index a1f3df1a0..aced2886a 100644 --- a/module/zfs/zfs_dir.c +++ b/module/zfs/zfs_dir.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 6a7623cae..593ed74bb 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 14411b8c4..7c980b118 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index e5e187b15..764f53040 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -68,10 +68,9 @@ #include #include #include -#include #include +#include #include "fs/fs_subr.h" -#include #include #include #include From eb28321e2d8952290db7dceb66d7761d528788e3 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:49:58 -0800 Subject: [PATCH 42/75] Create a root znode without VFS dependencies For portability reasons it's handy to be able to create a root znode and basic filesystem components without requiring the full cooperation of the VFS. We are committing to this to simply the filesystem creations code. --- module/zfs/zfs_znode.c | 89 ++---------------------------------------- 1 file changed, 4 insertions(+), 85 deletions(-) diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 61eb877aa..283b4d511 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -1484,23 +1484,12 @@ void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) { uint64_t moid, obj, sa_obj, version; - uint64_t sense = ZFS_CASE_SENSITIVE; uint64_t norm = 0; nvpair_t *elem; int error; -#ifdef HAVE_ZPL - zfsvfs_t zfsvfs; - int i; - znode_t *rootzp = NULL; - vnode_t *vp; - vattr_t vattr; - znode_t *zp; - zfs_acl_ids_t acl_ids; -#else timestruc_t now; dmu_buf_t *db; znode_phys_t *pzp; -#endif /* HAVE_ZPL */ /* * First attempt to create master node. @@ -1536,8 +1525,6 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) ASSERT(error == 0); if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0) norm = val; - else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0) - sense = val; } ASSERT(version != 0); error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx); @@ -1562,79 +1549,11 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx); ASSERT(error == 0); -#ifdef HAVE_ZPL /* - * Create root znode. Create minimal znode/vnode/zfsvfs - * to allow zfs_mknode to work. - */ - vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; - vattr.va_type = VDIR; - vattr.va_mode = S_IFDIR|0755; - vattr.va_uid = crgetuid(cr); - vattr.va_gid = crgetgid(cr); - - rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP); - ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs)); - rootzp->z_moved = 0; - rootzp->z_unlinked = 0; - rootzp->z_atime_dirty = 0; - rootzp->z_is_sa = USE_SA(version, os); - - vp = ZTOV(rootzp); - vn_reinit(vp); - vp->v_type = VDIR; - - bzero(&zfsvfs, sizeof (zfsvfs_t)); - - zfsvfs.z_os = os; - zfsvfs.z_parent = &zfsvfs; - zfsvfs.z_version = version; - zfsvfs.z_use_fuids = USE_FUIDS(version, os); - zfsvfs.z_use_sa = USE_SA(version, os); - zfsvfs.z_norm = norm; - - error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END, - &zfsvfs.z_attr_table); - - ASSERT(error == 0); - - /* - * Fold case on file systems that are always or sometimes case - * insensitive. - */ - if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED) - zfsvfs.z_norm |= U8_TEXTPREP_TOUPPER; - - /* XXX - This must be destroyed but I'm not quite sure yet so - * I'm just annotating that fact when it's an issue. -Brian */ - mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); - list_create(&zfsvfs.z_all_znodes, sizeof (znode_t), - offsetof(znode_t, z_link_node)); - - for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) - mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); - - rootzp->z_zfsvfs = &zfsvfs; - VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, - cr, NULL, &acl_ids)); - zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids); - ASSERT3P(zp, ==, rootzp); - ASSERT(!vn_in_dnlc(ZTOV(rootzp))); /* not valid to move */ - error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); - ASSERT(error == 0); - zfs_acl_ids_free(&acl_ids); - POINTER_INVALIDATE(&rootzp->z_zfsvfs); - - ZTOV(rootzp)->v_count = 0; - sa_handle_destroy(rootzp->z_sa_hdl); - kmem_cache_free(znode_cache, rootzp); - error = zfs_create_share_dir(&zfsvfs, tx); - - for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) - mutex_destroy(&zfsvfs.z_hold_mtx[i]); -#else - /* - * Create root znode with code free of VFS dependencies + * Create root znode with code free of VFS dependencies. This + * is important because without a registered filesystem and super + * block all the required VFS hooks will be missing. The critical + * thing is to just crete the required root znode. */ obj = zap_create_norm(os, norm, DMU_OT_DIRECTORY_CONTENTS, DMU_OT_ZNODE, sizeof (znode_phys_t), tx); From 6149f4c45fc905761a6f636ea9e14ff76ce6c842 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 8 Feb 2011 10:39:06 -0800 Subject: [PATCH 43/75] Remove dmu_write_pages() support For the moment we do not use dmu_write_pages() to write pages directly in to a dmu object. It may be required at some point in the future, but for now is simplest and cleanest to drop it. It can be easily readded if/when needed. --- include/sys/dmu.h | 4 ---- module/zfs/dmu.c | 57 ----------------------------------------------- 2 files changed, 61 deletions(-) diff --git a/include/sys/dmu.h b/include/sys/dmu.h index a8edfdbf8..7040b6740 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -522,10 +522,6 @@ int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size, dmu_tx_t *tx); int dmu_write_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size, dmu_tx_t *tx); -#ifdef HAVE_ZPL -int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, - uint64_t size, struct page *pp, dmu_tx_t *tx); -#endif #endif struct arc_buf *dmu_request_arcbuf(dmu_buf_t *handle, int size); void dmu_return_arcbuf(struct arc_buf *buf); diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index 79024e1ee..ede0d0517 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -1268,63 +1268,6 @@ dmu_write_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size, return (err); } - -#ifdef HAVE_ZPL -int -dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, - page_t *pp, dmu_tx_t *tx) -{ - dmu_buf_t **dbp; - int numbufs, i; - int err; - - if (size == 0) - return (0); - - err = dmu_buf_hold_array(os, object, offset, size, - FALSE, FTAG, &numbufs, &dbp); - if (err) - return (err); - - for (i = 0; i < numbufs; i++) { - int tocpy, copied, thiscpy; - int bufoff; - dmu_buf_t *db = dbp[i]; - caddr_t va; - - ASSERT(size > 0); - ASSERT3U(db->db_size, >=, PAGESIZE); - - bufoff = offset - db->db_offset; - tocpy = (int)MIN(db->db_size - bufoff, size); - - ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size); - - if (tocpy == db->db_size) - dmu_buf_will_fill(db, tx); - else - dmu_buf_will_dirty(db, tx); - - for (copied = 0; copied < tocpy; copied += PAGESIZE) { - ASSERT3U(pp->p_offset, ==, db->db_offset + bufoff); - thiscpy = MIN(PAGESIZE, tocpy - copied); - va = zfs_map_page(pp, S_READ); - bcopy(va, (char *)db->db_data + bufoff, thiscpy); - zfs_unmap_page(pp, va); - pp = pp->p_next; - bufoff += PAGESIZE; - } - - if (tocpy == db->db_size) - dmu_buf_fill_done(db, tx); - - offset += tocpy; - size -= tocpy; - } - dmu_buf_rele_array(dbp, numbufs, FTAG); - return (err); -} -#endif /* HAVE_ZPL */ #endif /* _KERNEL */ /* From 3558fd73b5d863304102f6745c26e0b592aca60a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 8 Feb 2011 11:16:06 -0800 Subject: [PATCH 44/75] Prototype/structure update for Linux I appologize in advance why to many things ended up in this commit. When it could be seperated in to a whole series of commits teasing that all apart now would take considerable time and I'm not sure there's much merrit in it. As such I'll just summerize the intent of the changes which are all (or partly) in this commit. Broadly the intent is to remove as much Solaris specific code as possible and replace it with native Linux equivilants. More specifically: 1) Replace all instances of zfsvfs_t with zfs_sb_t. While the type is largely the same calling it private super block data rather than a zfsvfs is more consistent with how Linux names this. While non critical it makes the code easier to read when your thinking in Linux friendly VFS terms. 2) Replace vnode_t with struct inode. The Linux VFS doesn't have the notion of a vnode and there's absolutely no good reason to create one. There are in fact several good reasons to remove it. It just adds overhead on Linux if we were to manage one, it conplicates the code, and it likely will lead to bugs so there's a good change it will be out of date. The code has been updated to remove all need for this type. 3) Replace all vtype_t's with umode types. Along with this shift all uses of types to mode bits. The Solaris code would pass a vtype which is redundant with the Linux mode. Just update all the code to use the Linux mode macros and remove this redundancy. 4) Remove using of vn_* helpers and replace where needed with inode helpers. The big example here is creating iput_aync to replace vn_rele_async. Other vn helpers will be addressed as needed but they should be be emulated. They are a Solaris VFS'ism and should simply be replaced with Linux equivilants. 5) Update znode alloc/free code. Under Linux it's common to embed the inode specific data with the inode itself. This removes the need for an extra memory allocation. In zfs this information is called a znode and it now embeds the inode with it. Allocators have been updated accordingly. 6) Minimal integration with the vfs flags for setting up the super block and handling mount options has been added this code will need to be refined but functionally it's all there. This will be the first and last of these to large to review commits. --- include/sys/dsl_pool.h | 4 +- include/sys/zfs_acl.h | 6 +- include/sys/zfs_dir.h | 8 +- include/sys/zfs_fuid.h | 18 +- include/sys/zfs_vfsops.h | 46 +- include/sys/zfs_vnops.h | 76 +- include/sys/zfs_znode.h | 76 +- module/zfs/dmu_objset.c | 2 - module/zfs/dsl_dataset.c | 2 - module/zfs/dsl_pool.c | 8 +- module/zfs/spa_config.c | 1 - module/zfs/vdev_file.c | 1 - module/zfs/zfs_acl.c | 281 +++-- module/zfs/zfs_dir.c | 285 ++--- module/zfs/zfs_fuid.c | 171 ++- module/zfs/zfs_ioctl.c | 205 ++-- module/zfs/zfs_log.c | 15 +- module/zfs/zfs_rlock.c | 2 +- module/zfs/zfs_sa.c | 78 +- module/zfs/zfs_vfsops.c | 1106 ++++++++---------- module/zfs/zfs_vnops.c | 2343 ++++++++++++-------------------------- module/zfs/zfs_znode.c | 720 +++++------- 22 files changed, 2103 insertions(+), 3351 deletions(-) diff --git a/include/sys/dsl_pool.h b/include/sys/dsl_pool.h index 7d25bd7c0..99a131eec 100644 --- a/include/sys/dsl_pool.h +++ b/include/sys/dsl_pool.h @@ -75,7 +75,7 @@ typedef struct dsl_pool { struct dsl_dir *dp_free_dir; struct dsl_dataset *dp_origin_snap; uint64_t dp_root_dir_obj; - struct taskq *dp_vnrele_taskq; + struct taskq *dp_iput_taskq; /* No lock needed - sync context only */ blkptr_t dp_meta_rootbp; @@ -135,7 +135,7 @@ void dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx); -taskq_t *dsl_pool_vnrele_taskq(dsl_pool_t *dp); +taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp); extern int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, const char *tag, uint64_t *now, dmu_tx_t *tx); diff --git a/include/sys/zfs_acl.h b/include/sys/zfs_acl.h index c1a0aeebd..6f7cef2ad 100644 --- a/include/sys/zfs_acl.h +++ b/include/sys/zfs_acl.h @@ -200,13 +200,13 @@ typedef struct zfs_acl_ids { #define ZFS_ACL_PASSTHROUGH_X 5 struct znode; -struct zfsvfs; +struct zfs_sb; #ifdef _KERNEL int zfs_acl_ids_create(struct znode *, int, vattr_t *, cred_t *, vsecattr_t *, zfs_acl_ids_t *); void zfs_acl_ids_free(zfs_acl_ids_t *); -boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *); +boolean_t zfs_acl_ids_overquota(struct zfs_sb *, zfs_acl_ids_t *); int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); int zfs_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); void zfs_acl_rele(void *); @@ -223,7 +223,7 @@ int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *); int zfs_zaccess_rename(struct znode *, struct znode *, struct znode *, struct znode *, cred_t *cr); void zfs_acl_free(zfs_acl_t *); -int zfs_vsec_2_aclp(struct zfsvfs *, vtype_t, vsecattr_t *, cred_t *, +int zfs_vsec_2_aclp(struct zfs_sb *, umode_t, vsecattr_t *, cred_t *, struct zfs_fuid_info **, zfs_acl_t **); int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, dmu_tx_t *); uint64_t zfs_external_acl(struct znode *); diff --git a/include/sys/zfs_dir.h b/include/sys/zfs_dir.h index 349f8ef37..8610fbe08 100644 --- a/include/sys/zfs_dir.h +++ b/include/sys/zfs_dir.h @@ -54,7 +54,7 @@ extern void zfs_dirent_unlock(zfs_dirlock_t *); extern int zfs_link_create(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int); extern int zfs_link_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int, boolean_t *); -extern int zfs_dirlook(znode_t *, char *, vnode_t **, int, int *, +extern int zfs_dirlook(znode_t *, char *, struct inode **, int, int *, pathname_t *); extern void zfs_mknode(znode_t *, vattr_t *, dmu_tx_t *, cred_t *, uint_t, znode_t **, zfs_acl_ids_t *); @@ -62,10 +62,10 @@ extern void zfs_rmnode(znode_t *); extern void zfs_dl_name_switch(zfs_dirlock_t *dl, char *new, char **old); extern boolean_t zfs_dirempty(znode_t *); extern void zfs_unlinked_add(znode_t *, dmu_tx_t *); -extern void zfs_unlinked_drain(zfsvfs_t *zfsvfs); +extern void zfs_unlinked_drain(zfs_sb_t *); extern int zfs_sticky_remove_access(znode_t *, znode_t *, cred_t *cr); -extern int zfs_get_xattrdir(znode_t *, vnode_t **, cred_t *, int); -extern int zfs_make_xattrdir(znode_t *, vattr_t *, vnode_t **, cred_t *); +extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int); +extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *); #ifdef __cplusplus } diff --git a/include/sys/zfs_fuid.h b/include/sys/zfs_fuid.h index 91650a22d..deaebcc82 100644 --- a/include/sys/zfs_fuid.h +++ b/include/sys/zfs_fuid.h @@ -100,24 +100,24 @@ typedef struct zfs_fuid_info { #ifdef _KERNEL struct znode; -extern uid_t zfs_fuid_map_id(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t); +extern uid_t zfs_fuid_map_id(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t); extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t, uint64_t, uint64_t, zfs_fuid_type_t); -extern void zfs_fuid_destroy(zfsvfs_t *); -extern uint64_t zfs_fuid_create_cred(zfsvfs_t *, zfs_fuid_type_t, +extern void zfs_fuid_destroy(zfs_sb_t *); +extern uint64_t zfs_fuid_create_cred(zfs_sb_t *, zfs_fuid_type_t, cred_t *, zfs_fuid_info_t **); -extern uint64_t zfs_fuid_create(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t, +extern uint64_t zfs_fuid_create(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t, zfs_fuid_info_t **); extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr, uid_t *uid, uid_t *gid); extern zfs_fuid_info_t *zfs_fuid_info_alloc(void); extern void zfs_fuid_info_free(zfs_fuid_info_t *); -extern boolean_t zfs_groupmember(zfsvfs_t *, uint64_t, cred_t *); -void zfs_fuid_sync(zfsvfs_t *, dmu_tx_t *); -extern int zfs_fuid_find_by_domain(zfsvfs_t *, const char *domain, +extern boolean_t zfs_groupmember(zfs_sb_t *, uint64_t, cred_t *); +void zfs_fuid_sync(zfs_sb_t *, dmu_tx_t *); +extern int zfs_fuid_find_by_domain(zfs_sb_t *, const char *domain, char **retdomain, boolean_t addok); -extern const char *zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx); -extern void zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx); +extern const char *zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx); +extern void zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx); #endif char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t); diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 34a871587..a2f00acf0 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -38,13 +38,15 @@ extern "C" { #endif -typedef struct zfsvfs zfsvfs_t; +struct zfs_sb; struct znode; -struct zfsvfs { - vfs_t *z_vfs; /* generic fs struct */ - zfsvfs_t *z_parent; /* parent fs */ +typedef struct zfs_sb { + struct vfsmount *z_vfs; /* generic vfs struct */ + struct super_block *z_sb; /* generic super_block */ + struct zfs_sb *z_parent; /* parent fs */ objset_t *z_os; /* objset reference */ + uint64_t z_flags; /* super_block flags */ uint64_t z_root; /* id of root znode */ uint64_t z_unlinkedobj; /* id of unlinked zapobj */ uint64_t z_max_blksz; /* maximum block size for files */ @@ -87,6 +89,8 @@ struct zfsvfs { #define ZFS_SUPER_MAGIC 0x2fc12fc1 +#define ZSB_XATTR_USER 0x0001 /* Enable user xattrs */ + /* * Minimal snapshot helpers, the bulk of the Linux snapshot implementation @@ -162,30 +166,30 @@ typedef struct zfid_long { extern uint_t zfs_fsyncer_key; -extern int zfs_suspend_fs(zfsvfs_t *zfsvfs); -extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname); -extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +extern int zfs_suspend_fs(zfs_sb_t *zsb); +extern int zfs_resume_fs(zfs_sb_t *zsb, const char *osname); +extern int zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t *valuep); -extern int zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +extern int zfs_userspace_many(zfs_sb_t *zsb, zfs_userquota_prop_t type, uint64_t *cookiep, void *vbuf, uint64_t *bufsizep); -extern int zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +extern int zfs_set_userquota(zfs_sb_t *zsb, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t quota); -extern boolean_t zfs_owner_overquota(zfsvfs_t *zfsvfs, struct znode *, +extern boolean_t zfs_owner_overquota(zfs_sb_t *zsb, struct znode *, boolean_t isgroup); -extern boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, +extern boolean_t zfs_fuid_overquota(zfs_sb_t *zsb, boolean_t isgroup, uint64_t fuid); -extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers); -extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp); -extern void zfsvfs_free(zfsvfs_t *zfsvfs); +extern int zfs_set_version(zfs_sb_t *zsb, uint64_t newvers); +extern int zfs_sb_create(const char *name, zfs_sb_t **zsbp); +extern void zfs_sb_free(zfs_sb_t *zsb); extern int zfs_check_global_label(const char *dsname, const char *hexsl); -extern int zfs_register_callbacks(vfs_t *vfsp); -extern void zfs_unregister_callbacks(zfsvfs_t *zfsvfs); -extern int zfs_domount(vfs_t *vfsp, char *osname); -extern int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr); -extern int zfs_root(vfs_t *vfsp, vnode_t **vpp); -extern int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp); -extern int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp); +extern int zfs_register_callbacks(zfs_sb_t *zsb); +extern void zfs_unregister_callbacks(zfs_sb_t *zsb); +extern int zfs_domount(struct super_block *sb, void *data, int silent); +extern int zfs_umount(struct super_block *sb); +extern int zfs_root(zfs_sb_t *zsb, struct inode **ipp); +extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp); +extern int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp); #ifdef __cplusplus } diff --git a/include/sys/zfs_vnops.h b/include/sys/zfs_vnops.h index 64e2210de..2cacb9c6f 100644 --- a/include/sys/zfs_vnops.h +++ b/include/sys/zfs_vnops.h @@ -28,50 +28,48 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif -extern int zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, - caller_context_t *ct); -extern int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, - caller_context_t *ct); -extern int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, - struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr, - caller_context_t *ct, int *direntflags, pathname_t *realpnp); -extern int zfs_create(vnode_t *dvp, char *name, vattr_t *vap, - int excl, int mode, vnode_t **vpp, cred_t *cr, int flag, - caller_context_t *ct, vsecattr_t *vsecp); -extern int zfs_remove(vnode_t *dvp, char *name, cred_t *cr, - caller_context_t *ct, int flags); -extern int zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, - vnode_t **vpp, cred_t *cr, caller_context_t *ct, int flags, - vsecattr_t *vsecp); -extern int zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, - caller_context_t *ct, int flags); -extern int zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, - caller_context_t *ct); -extern int zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct); -extern int zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct); -extern int zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, - cred_t *cr, caller_context_t *ct, int flags); -extern int zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, - cred_t *cr, caller_context_t *ct, int flags); -extern int zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, - caller_context_t *ct); -extern int zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, - caller_context_t *ct, int flags); -extern void zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct); -extern int zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, - offset_t offset, cred_t *cr, caller_context_t *ct); -extern int zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct); -extern int zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, - cred_t *cr, caller_context_t *ct); -extern int zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, - cred_t *cr, caller_context_t *ct); +extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); +extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); +extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr); +extern int zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, + int flags, cred_t *cr, int *direntflags, pathname_t *realpnp); +extern int zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl, + int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp); +extern int zfs_remove(struct inode *dip, char *name, cred_t *cr); +extern int zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, + struct inode **ipp, cred_t *cr, int flags, vsecattr_t *vsecp); +extern int zfs_rmdir(struct inode *dip, char *name, struct inode *cwd, + cred_t *cr, int flags); +extern int zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir, + loff_t *pos, cred_t *cr); +extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr); +extern int zfs_getattr(struct inode *ip, struct kstat *stat, int flag, + cred_t *cr); +extern int zfs_setattr(struct inode *ip, struct iattr *attr, int flag, + cred_t *cr); +extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, + char *tnm, cred_t *cr, int flags); +extern int zfs_symlink(struct inode *dip, char *name, vattr_t *vap, + char *link, struct inode **ipp, cred_t *cr, int flags); +extern int zfs_follow_link(struct dentry *dentry, struct nameidata *nd); +extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr); +extern int zfs_link(struct inode *tdip, struct inode *sip, + char *name, cred_t *cr); +extern void zfs_inactive(struct inode *ip); +extern int zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag, + offset_t offset, cred_t *cr); +extern int zfs_fid(struct inode *ip, fid_t *fidp); +extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, + cred_t *cr); +extern int zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, + cred_t *cr); #ifdef __cplusplus } diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 4dbecb4b5..2f25cc7fe 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -69,7 +69,7 @@ extern "C" { pflags |= attr; \ else \ pflags &= ~attr; \ - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zp->z_zfsvfs), \ + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zp->z_sb), \ &pflags, sizeof (pflags), tx)); \ } @@ -181,8 +181,6 @@ typedef struct zfs_dirlock { } zfs_dirlock_t; typedef struct znode { - struct zfsvfs *z_zfsvfs; - vnode_t *z_vnode; uint64_t z_id; /* object ID for this znode */ kmutex_t z_lock; /* znode modification lock */ krwlock_t z_parent_lock; /* parent lock for directories */ @@ -235,48 +233,52 @@ typedef struct znode { /* * Convert between znode pointers and inode pointers */ -#define ZTOI(ZP) (&((ZP)->z_inode)) -#define ITOZ(IP) (container_of((IP), znode_t, z_inode)) - -/* XXX - REMOVE ME ONCE THE OTHER BUILD ISSUES ARE RESOLVED */ -#define ZTOV(ZP) ((ZP)->z_vnode) -#define VTOZ(VP) ((znode_t *)(VP)->v_data) +#define ZTOI(znode) (&((znode)->z_inode)) +#define ITOZ(inode) (container_of((inode), znode_t, z_inode)) +#define VTOZSB(vfs) ((zfs_sb_t *)((vfs)->mnt_sb->s_fs_info)) +#define ZTOZSB(znode) ((zfs_sb_t *)(ZTOI(znode)->i_sb->s_fs_info)) +#define ITOZSB(inode) ((zfs_sb_t *)((inode)->i_sb->s_fs_info)) +#define S_ISDEV(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) /* * ZFS_ENTER() is called on entry to each ZFS inode and vfs operation. * ZFS_EXIT() must be called before exitting the vop. * ZFS_VERIFY_ZP() verifies the znode is valid. */ -#define ZFS_ENTER(zfsvfs) \ +#define ZFS_ENTER(zsb) \ { \ - rrw_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG); \ - if ((zfsvfs)->z_unmounted) { \ - ZFS_EXIT(zfsvfs); \ + rrw_enter(&(zsb)->z_teardown_lock, RW_READER, FTAG); \ + if ((zsb)->z_unmounted) { \ + ZFS_EXIT(zsb); \ return (EIO); \ } \ } -#define ZFS_EXIT(zfsvfs) rrw_exit(&(zfsvfs)->z_teardown_lock, FTAG) +#define ZFS_EXIT(zsb) \ + { \ + rrw_exit(&(zsb)->z_teardown_lock, FTAG); \ + tsd_exit(); \ + } #define ZFS_VERIFY_ZP(zp) \ if ((zp)->z_sa_hdl == NULL) { \ - ZFS_EXIT((zp)->z_zfsvfs); \ + ZFS_EXIT(ZTOZSB(zp)); \ return (EIO); \ - } \ + } /* * Macros for dealing with dmu_buf_hold */ #define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1)) -#define ZFS_OBJ_MUTEX(zfsvfs, obj_num) \ - (&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) -#define ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num) \ - mutex_enter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) -#define ZFS_OBJ_HOLD_TRYENTER(zfsvfs, obj_num) \ - mutex_tryenter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) -#define ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num) \ - mutex_exit(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) +#define ZFS_OBJ_MUTEX(zsb, obj_num) \ + (&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) +#define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \ + mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num))) +#define ZFS_OBJ_HOLD_TRYENTER(zsb, obj_num) \ + mutex_tryenter(ZFS_OBJ_MUTEX((zsb), (obj_num))) +#define ZFS_OBJ_HOLD_EXIT(zsb, obj_num) \ + mutex_exit(ZFS_OBJ_MUTEX((zsb), (obj_num))) /* * Macros to encode/decode ZFS stored time values from/to struct timespec @@ -296,15 +298,15 @@ typedef struct znode { /* * Timestamp defines */ -#define ACCESSED (AT_ATIME) -#define STATE_CHANGED (AT_CTIME) -#define CONTENT_MODIFIED (AT_MTIME | AT_CTIME) +#define ACCESSED (ATTR_ATIME) +#define STATE_CHANGED (ATTR_CTIME) +#define CONTENT_MODIFIED (ATTR_MTIME | ATTR_CTIME) -#define ZFS_ACCESSTIME_STAMP(zfsvfs, zp) \ - if ((zfsvfs)->z_atime && !((zfsvfs)->z_vfs->vfs_flag & VFS_RDONLY)) \ +#define ZFS_ACCESSTIME_STAMP(zsb, zp) \ + if ((zsb)->z_atime && !((zsb)->z_vfs->mnt_flags & MNT_READONLY)) \ zfs_tstamp_update_setup(zp, ACCESSED, NULL, NULL, B_FALSE); -extern int zfs_init_fs(zfsvfs_t *, znode_t **); +extern int zfs_init_fs(zfs_sb_t *, znode_t **); extern void zfs_set_dataprop(objset_t *); extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *, dmu_tx_t *tx); @@ -314,18 +316,19 @@ extern void zfs_grow_blocksize(znode_t *, uint64_t, dmu_tx_t *); extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t); extern void zfs_znode_init(void); extern void zfs_znode_fini(void); -extern int zfs_zget(zfsvfs_t *, uint64_t, znode_t **); +extern int zfs_zget(zfs_sb_t *, uint64_t, znode_t **); extern int zfs_rezget(znode_t *); extern void zfs_zinactive(znode_t *); extern void zfs_znode_delete(znode_t *, dmu_tx_t *); -extern void zfs_znode_free(znode_t *); extern void zfs_remove_op_tables(void); extern int zfs_create_op_tables(void); -extern int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr); +extern int zfs_sync(zfs_sb_t *, short, cred_t *); extern dev_t zfs_cmpldev(uint64_t); extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value); extern int zfs_get_stats(objset_t *os, nvlist_t *nv); extern void zfs_znode_dmu_fini(znode_t *); +extern int zfs_inode_alloc(struct super_block *, struct inode **ip); +extern void zfs_inode_destroy(struct inode *); extern void zfs_inode_update(znode_t *); extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, @@ -347,12 +350,13 @@ extern void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, extern void zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype, znode_t *zp, uint64_t off, uint64_t len); extern void zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, - znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp); + znode_t *zp, struct iattr *attr, uint_t mask_applied, + zfs_fuid_info_t *fuidp); extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, vsecattr_t *vsecp, zfs_fuid_info_t *fuidp); extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx); -extern void zfs_upgrade(zfsvfs_t *zfsvfs, dmu_tx_t *tx); -extern int zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx); +extern void zfs_upgrade(zfs_sb_t *zsb, dmu_tx_t *tx); +extern int zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx); #if defined(HAVE_UIO_RW) extern caddr_t zfs_map_page(page_t *, enum seg_rw); diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 7da5c1aa0..cbd177819 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -910,10 +910,8 @@ dmu_objset_snapshot_one(const char *name, void *arg) * permission checks for the starting dataset have already been * performed in zfs_secpolicy_snapshot() */ -#ifdef HAVE_ZPL if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED()))) return (err); -#endif err = dmu_objset_hold(name, sn, &os); if (err != 0) diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index dfccede04..c34ac2a76 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -2364,13 +2364,11 @@ dsl_snapshot_rename_one(const char *name, void *arg) * For recursive snapshot renames the parent won't be changing * so we just pass name for both the to/from argument. */ -#ifdef HAVE_ZPL err = zfs_secpolicy_rename_perms(snapname, snapname, CRED()); if (err != 0) { strfree(snapname); return (err == ENOENT ? 0 : err); } -#endif /* XXX: Ignore for SPL version until mounting the FS is supported */ #if defined(_KERNEL) && !defined(HAVE_SPL) diff --git a/module/zfs/dsl_pool.c b/module/zfs/dsl_pool.c index 6a0e3632c..7185540f1 100644 --- a/module/zfs/dsl_pool.c +++ b/module/zfs/dsl_pool.c @@ -92,7 +92,7 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg) mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL); - dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri, + dp->dp_iput_taskq = taskq_create("zfs_iput_taskq", 1, minclsyspri, 1, 4, 0); return (dp); @@ -214,7 +214,7 @@ dsl_pool_close(dsl_pool_t *dp) dsl_scan_fini(dp); rw_destroy(&dp->dp_config_rwlock); mutex_destroy(&dp->dp_lock); - taskq_destroy(dp->dp_vnrele_taskq); + taskq_destroy(dp->dp_iput_taskq); if (dp->dp_blkstats) kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t)); kmem_free(dp, sizeof (dsl_pool_t)); @@ -738,9 +738,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx) } taskq_t * -dsl_pool_vnrele_taskq(dsl_pool_t *dp) +dsl_pool_iput_taskq(dsl_pool_t *dp) { - return (dp->dp_vnrele_taskq); + return (dp->dp_iput_taskq); } /* diff --git a/module/zfs/spa_config.c b/module/zfs/spa_config.c index 79664cbe1..d84d6b0f9 100644 --- a/module/zfs/spa_config.c +++ b/module/zfs/spa_config.c @@ -179,7 +179,6 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); } (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); - VN_RELE(vp); } (void) vn_remove(temp, UIO_SYSSPACE, RMFILE); diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index f31389a6d..bbc85e733 100644 --- a/module/zfs/vdev_file.c +++ b/module/zfs/vdev_file.c @@ -130,7 +130,6 @@ vdev_file_close(vdev_t *vd) (void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL); (void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0, kcred, NULL); - VN_RELE(vf->vf_vnode); } vd->vdev_delayed_close = B_FALSE; diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index 45ec20647..0ae749e6b 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -345,7 +345,7 @@ zfs_external_acl(znode_t *zp) * changed. */ - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zp->z_zfsvfs), + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(ZTOZSB(zp)), &acl_phys, sizeof (acl_phys))) == 0) return (acl_phys.z_acl_extern_obj); else { @@ -368,23 +368,23 @@ static int zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount, zfs_acl_phys_t *aclphys) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); uint64_t acl_count; int size; int error; ASSERT(MUTEX_HELD(&zp->z_acl_lock)); if (zp->z_is_sa) { - if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zfsvfs), + if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zsb), &size)) != 0) return (error); *aclsize = size; - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zfsvfs), + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zsb), &acl_count, sizeof (acl_count))) != 0) return (error); *aclcount = acl_count; } else { - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs), + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb), aclphys, sizeof (*aclphys))) != 0) return (error); @@ -418,7 +418,7 @@ zfs_znode_acl_version(znode_t *zp) * changed. */ if ((error = sa_lookup(zp->z_sa_hdl, - SA_ZPL_ZNODE_ACL(zp->z_zfsvfs), + SA_ZPL_ZNODE_ACL(ZTOZSB(zp)), &acl_phys, sizeof (acl_phys))) == 0) return (acl_phys.z_acl_version); else { @@ -444,7 +444,7 @@ zfs_acl_version(int version) static int zfs_acl_version_zp(znode_t *zp) { - return (zfs_acl_version(zp->z_zfsvfs->z_version)); + return (zfs_acl_version(ZTOZSB(zp)->z_version)); } zfs_acl_t * @@ -531,7 +531,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags) } static boolean_t -zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) +zfs_ace_valid(umode_t obj_mode, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) { /* * first check type of entry @@ -554,7 +554,7 @@ zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) * next check inheritance level flags */ - if (obj_type == VDIR && + if (S_ISDIR(obj_mode) && (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE))) aclp->z_hints |= ZFS_INHERIT_ACE; @@ -648,7 +648,7 @@ zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt, * ACE FUIDs will be created later. */ int -zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, +zfs_copy_ace_2_fuid(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *aclp, void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size, zfs_fuid_info_t **fuidp, cred_t *cr) { @@ -666,7 +666,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && entry_type != ACE_EVERYONE) { - aceptr->z_fuid = zfs_fuid_create(zfsvfs, acep->a_who, + aceptr->z_fuid = zfs_fuid_create(zsb, acep->a_who, cr, (entry_type == 0) ? ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp); } @@ -674,7 +674,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, /* * Make sure ACE is valid */ - if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type, + if (zfs_ace_valid(obj_mode, aclp, aceptr->z_hdr.z_type, aceptr->z_hdr.z_flags) != B_TRUE) return (EINVAL); @@ -710,7 +710,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, * Copy ZFS ACEs to fixed size ace_t layout */ static void -zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, +zfs_copy_fuid_2_ace(zfs_sb_t *zsb, zfs_acl_t *aclp, cred_t *cr, void *datap, int filter) { uint64_t who; @@ -753,7 +753,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, if ((entry_type != ACE_OWNER && entry_type != OWNING_GROUP && entry_type != ACE_EVERYONE)) { - acep->a_who = zfs_fuid_map_id(zfsvfs, who, + acep->a_who = zfs_fuid_map_id(zsb, who, cr, (entry_type & ACE_IDENTIFIER_GROUP) ? ZFS_ACE_GROUP : ZFS_ACE_USER); } else { @@ -767,7 +767,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, } static int -zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, +zfs_copy_ace_2_oldace(umode_t obj_mode, zfs_acl_t *aclp, ace_t *acep, zfs_oldace_t *z_acl, int aclcnt, size_t *size) { int i; @@ -781,7 +781,7 @@ zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, /* * Make sure ACE is valid */ - if (zfs_ace_valid(obj_type, aclp, aceptr->z_type, + if (zfs_ace_valid(obj_mode, aclp, aceptr->z_type, aceptr->z_flags) != B_TRUE) return (EINVAL); } @@ -825,8 +825,8 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr) newaclnode = zfs_acl_node_alloc(aclp->z_acl_count * sizeof (zfs_object_ace_t)); aclp->z_ops = zfs_acl_fuid_ops; - VERIFY(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp, - oldaclp, newaclnode->z_acldata, aclp->z_acl_count, + VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode, + aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count, &newaclnode->z_size, NULL, cr) == 0); newaclnode->z_ace_count = aclp->z_acl_count; aclp->z_version = ZFS_ACL_VERSION; @@ -1100,7 +1100,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp, if (!zp->z_is_sa) { if (znode_acl.z_acl_extern_obj) { - error = dmu_read(zp->z_zfsvfs->z_os, + error = dmu_read(ZTOZSB(zp)->z_os, znode_acl.z_acl_extern_obj, 0, aclnode->z_size, aclnode->z_acldata, DMU_READ_PREFETCH); } else { @@ -1108,7 +1108,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp, aclnode->z_size); } } else { - error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zp->z_zfsvfs), + error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(ZTOZSB(zp)), aclnode->z_acldata, aclnode->z_size); } @@ -1295,7 +1295,7 @@ int zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) { int error; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); dmu_object_type_t otype; zfs_acl_locator_cb_t locate = { 0 }; uint64_t mode; @@ -1309,11 +1309,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) zp->z_uid, zp->z_gid); zp->z_mode = mode; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, sizeof (mode)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, sizeof (zp->z_pflags)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, sizeof (ctime)); if (zp->z_acl_cached) { @@ -1324,11 +1324,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) /* * Upgrade needed? */ - if (!zfsvfs->z_use_fuids) { + if (!zsb->z_use_fuids) { otype = DMU_OT_OLDACL; } else { if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) && - (zfsvfs->z_version >= ZPL_VERSION_FUID)) + (zsb->z_version >= ZPL_VERSION_FUID)) zfs_acl_xform(zp, aclp, cr); ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID); otype = DMU_OT_ACL; @@ -1341,9 +1341,9 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */ locate.cb_aclp = aclp; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zsb), zfs_acl_data_locator, &locate, aclp->z_acl_bytes); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zsb), NULL, &aclp->z_acl_count, sizeof (uint64_t)); } else { /* Painful legacy way */ zfs_acl_node_t *aclnode; @@ -1351,7 +1351,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) zfs_acl_phys_t acl_phys; uint64_t aoid; - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs), + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb), &acl_phys, sizeof (acl_phys))) != 0) return (error); @@ -1365,20 +1365,20 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) */ if (aoid && aclp->z_version != acl_phys.z_acl_version) { - error = dmu_object_free(zfsvfs->z_os, aoid, tx); + error = dmu_object_free(zsb->z_os, aoid, tx); if (error) return (error); aoid = 0; } if (aoid == 0) { - aoid = dmu_object_alloc(zfsvfs->z_os, + aoid = dmu_object_alloc(zsb->z_os, otype, aclp->z_acl_bytes, otype == DMU_OT_ACL ? DMU_OT_SYSACL : DMU_OT_NONE, otype == DMU_OT_ACL ? DN_MAX_BONUSLEN : 0, tx); } else { - (void) dmu_object_set_blocksize(zfsvfs->z_os, + (void) dmu_object_set_blocksize(zsb->z_os, aoid, aclp->z_acl_bytes, 0, tx); } acl_phys.z_acl_extern_obj = aoid; @@ -1386,7 +1386,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) aclnode = list_next(&aclp->z_acl, aclnode)) { if (aclnode->z_ace_count == 0) continue; - dmu_write(zfsvfs->z_os, aoid, off, + dmu_write(zsb->z_os, aoid, off, aclnode->z_size, aclnode->z_acldata, tx); off += aclnode->z_size; } @@ -1396,7 +1396,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) * Migrating back embedded? */ if (acl_phys.z_acl_extern_obj) { - error = dmu_object_free(zfsvfs->z_os, + error = dmu_object_free(zsb->z_os, acl_phys.z_acl_extern_obj, tx); if (error) return (error); @@ -1425,7 +1425,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) } acl_phys.z_acl_version = aclp->z_version; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL, &acl_phys, sizeof (acl_phys)); } @@ -1444,19 +1444,19 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) } static void -zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp) +zfs_acl_chmod(zfs_sb_t *zsb, uint64_t mode, zfs_acl_t *aclp) { void *acep = NULL; uint64_t who; int new_count, new_bytes; int ace_size; - int entry_type; + int entry_type; uint16_t iflags, type; uint32_t access_mask; zfs_acl_node_t *newnode; - size_t abstract_size = aclp->z_ops.ace_abstract_size(); - void *zacep; - uint32_t owner, group, everyone; + size_t abstract_size = aclp->z_ops.ace_abstract_size(); + void *zacep; + uint32_t owner, group, everyone; uint32_t deny1, deny2, allow0; new_count = new_bytes = 0; @@ -1516,7 +1516,7 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp) * Limit permissions to be no greater than * group permissions */ - if (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) { + if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) { if (!(mode & S_IRGRP)) access_mask &= ~ACE_READ_DATA; if (!(mode & S_IWGRP)) @@ -1558,7 +1558,7 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode) mutex_enter(&zp->z_lock); *aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); (*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS; - zfs_acl_chmod(zp->z_zfsvfs, mode, *aclp); + zfs_acl_chmod(ZTOZSB(zp), mode, *aclp); mutex_exit(&zp->z_lock); mutex_exit(&zp->z_acl_lock); ASSERT(*aclp); @@ -1568,11 +1568,11 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode) * strip off write_owner and write_acl */ static void -zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep) +zfs_restricted_update(zfs_sb_t *zsb, zfs_acl_t *aclp, void *acep) { uint32_t mask = aclp->z_ops.ace_mask_get(acep); - if ((zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) && + if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) && (aclp->z_ops.ace_type_get(acep) == ALLOW)) { mask &= ~RESTRICTED_CLEAR; aclp->z_ops.ace_mask_set(acep, mask); @@ -1583,14 +1583,14 @@ zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep) * Should ACE be inherited? */ static int -zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags) +zfs_ace_can_use(umode_t obj_mode, uint16_t acep_flags) { int iflags = (acep_flags & 0xf); - if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) + if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) return (1); else if (iflags & ACE_FILE_INHERIT_ACE) - return (!((vtype == VDIR) && + return (!(S_ISDIR(obj_mode) && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE))); return (0); } @@ -1599,7 +1599,7 @@ zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags) * inherit inheritable ACEs from parent */ static zfs_acl_t * -zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, +zfs_acl_inherit(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *paclp, uint64_t mode, boolean_t *need_chmod) { void *pacep; @@ -1612,21 +1612,21 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, size_t ace_size; void *data1, *data2; size_t data1sz, data2sz; - boolean_t vdir = vtype == VDIR; - boolean_t vreg = vtype == VREG; + boolean_t vdir = S_ISDIR(obj_mode); + boolean_t vreg = S_ISREG(obj_mode); boolean_t passthrough, passthrough_x, noallow; passthrough_x = - zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X; + zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X; passthrough = passthrough_x || - zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH; + zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH; noallow = - zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW; + zsb->z_acl_inherit == ZFS_ACL_NOALLOW; *need_chmod = B_TRUE; pacep = NULL; aclp = zfs_acl_alloc(paclp->z_version); - if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD || vtype == VLNK) + if (zsb->z_acl_inherit == ZFS_ACL_DISCARD || S_ISLNK(obj_mode)) return (aclp); while ((pacep = zfs_acl_next_ace(paclp, pacep, &who, &access_mask, &iflags, &type))) { @@ -1642,7 +1642,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, ace_size = aclp->z_ops.ace_size(pacep); - if (!zfs_ace_can_use(vtype, iflags)) + if (!zfs_ace_can_use(obj_mode, iflags)) continue; /* @@ -1690,7 +1690,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, newflags &= ~ALL_INHERIT; aclp->z_ops.ace_flags_set(acep, newflags|ACE_INHERITED_ACE); - zfs_restricted_update(zfsvfs, aclp, acep); + zfs_restricted_update(zsb, aclp, acep); continue; } @@ -1723,7 +1723,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids) { int error; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); zfs_acl_t *paclp; #ifdef HAVE_KSID gid_t gid; @@ -1732,11 +1732,11 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, boolean_t inherited = B_FALSE; bzero(acl_ids, sizeof (zfs_acl_ids_t)); - acl_ids->z_mode = MAKEIMODE(vap->va_type, vap->va_mode); + acl_ids->z_mode = vap->va_mode; if (vsecp) - if ((error = zfs_vsec_2_aclp(zfsvfs, vap->va_type, vsecp, cr, - &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0) + if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp, + cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0) return (error); acl_ids->z_fuid = vap->va_uid; @@ -1745,21 +1745,19 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, /* * Determine uid and gid. */ - if ((flag & IS_ROOT_NODE) || zfsvfs->z_replay || - ((flag & IS_XATTR) && (vap->va_type == VDIR))) { - acl_ids->z_fuid = zfs_fuid_create(zfsvfs, - (uint64_t)vap->va_uid, cr, - ZFS_OWNER, &acl_ids->z_fuidp); - acl_ids->z_fgid = zfs_fuid_create(zfsvfs, - (uint64_t)vap->va_gid, cr, - ZFS_GROUP, &acl_ids->z_fuidp); + if ((flag & IS_ROOT_NODE) || zsb->z_replay || + ((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) { + acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid, + cr, ZFS_OWNER, &acl_ids->z_fuidp); + acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid, + cr, ZFS_GROUP, &acl_ids->z_fuidp); gid = vap->va_gid; } else { - acl_ids->z_fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER, + acl_ids->z_fuid = zfs_fuid_create_cred(zsb, ZFS_OWNER, cr, &acl_ids->z_fuidp); acl_ids->z_fgid = 0; if (vap->va_mask & AT_GID) { - acl_ids->z_fgid = zfs_fuid_create(zfsvfs, + acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid, cr, ZFS_GROUP, &acl_ids->z_fuidp); gid = vap->va_gid; @@ -1774,13 +1772,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, uint32_t rid; acl_ids->z_fgid = dzp->z_gid; - gid = zfs_fuid_map_id(zfsvfs, acl_ids->z_fgid, + gid = zfs_fuid_map_id(zsb, acl_ids->z_fgid, cr, ZFS_GROUP); - if (zfsvfs->z_use_fuids && + if (zsb->z_use_fuids && IS_EPHEMERAL(acl_ids->z_fgid)) { domain = zfs_fuid_idx_domain( - &zfsvfs->z_fuid_idx, + &zsb->z_fuid_idx, FUID_INDEX(acl_ids->z_fgid)); rid = FUID_RID(acl_ids->z_fgid); zfs_fuid_node_add(&acl_ids->z_fuidp, @@ -1789,7 +1787,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, acl_ids->z_fgid, ZFS_GROUP); } } else { - acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs, + acl_ids->z_fgid = zfs_fuid_create_cred(zsb, ZFS_GROUP, cr, &acl_ids->z_fuidp); gid = crgetgid(cr); } @@ -1805,7 +1803,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, */ if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) && - (vap->va_type == VDIR)) { + (S_ISDIR(vap->va_mode))) { acl_ids->z_mode |= S_ISGID; } else { if ((acl_ids->z_mode & S_ISGID) && @@ -1816,13 +1814,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, if (acl_ids->z_aclp == NULL) { mutex_enter(&dzp->z_acl_lock); mutex_enter(&dzp->z_lock); - if (!(flag & IS_ROOT_NODE) && (ZTOV(dzp)->v_type == VDIR && + if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) && (dzp->z_pflags & ZFS_INHERIT_ACE)) && !(dzp->z_pflags & ZFS_XATTR)) { VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE, &paclp, B_FALSE)); - acl_ids->z_aclp = zfs_acl_inherit(zfsvfs, - vap->va_type, paclp, acl_ids->z_mode, &need_chmod); + acl_ids->z_aclp = zfs_acl_inherit(zsb, + vap->va_mode, paclp, acl_ids->z_mode, &need_chmod); inherited = B_TRUE; } else { acl_ids->z_aclp = @@ -1832,9 +1830,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, mutex_exit(&dzp->z_lock); mutex_exit(&dzp->z_acl_lock); if (need_chmod) { - acl_ids->z_aclp->z_hints |= (vap->va_type == VDIR) ? + acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ? ZFS_ACL_AUTO_INHERIT : 0; - zfs_acl_chmod(zfsvfs, acl_ids->z_mode, acl_ids->z_aclp); + zfs_acl_chmod(zsb, acl_ids->z_mode, acl_ids->z_aclp); } } @@ -1864,10 +1862,10 @@ zfs_acl_ids_free(zfs_acl_ids_t *acl_ids) } boolean_t -zfs_acl_ids_overquota(zfsvfs_t *zfsvfs, zfs_acl_ids_t *acl_ids) +zfs_acl_ids_overquota(zfs_sb_t *zsb, zfs_acl_ids_t *acl_ids) { - return (zfs_fuid_overquota(zfsvfs, B_FALSE, acl_ids->z_fuid) || - zfs_fuid_overquota(zfsvfs, B_TRUE, acl_ids->z_fgid)); + return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) || + zfs_fuid_overquota(zsb, B_TRUE, acl_ids->z_fgid)); } /* @@ -1939,7 +1937,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) vsecp->vsa_aclentsz = aclsz; if (aclp->z_version == ZFS_ACL_VERSION_FUID) - zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr, + zfs_copy_fuid_2_ace(ZTOZSB(zp), aclp, cr, vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES)); else { zfs_acl_node_t *aclnode; @@ -1971,7 +1969,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) } int -zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, +zfs_vsec_2_aclp(zfs_sb_t *zsb, umode_t obj_mode, vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp) { zfs_acl_t *aclp; @@ -1982,12 +1980,12 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0) return (EINVAL); - aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version)); + aclp = zfs_acl_alloc(zfs_acl_version(zsb->z_version)); aclp->z_hints = 0; aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t)); if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) { - if ((error = zfs_copy_ace_2_oldace(obj_type, aclp, + if ((error = zfs_copy_ace_2_oldace(obj_mode, aclp, (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt, &aclnode->z_size)) != 0) { zfs_acl_free(aclp); @@ -1995,7 +1993,7 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, return (error); } } else { - if ((error = zfs_copy_ace_2_fuid(zfsvfs, obj_type, aclp, + if ((error = zfs_copy_ace_2_fuid(zsb, obj_mode, aclp, vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt, &aclnode->z_size, fuidp, cr)) != 0) { zfs_acl_free(aclp); @@ -2031,8 +2029,8 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, int zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - zilog_t *zilog = zfsvfs->z_log; + zfs_sb_t *zsb = ZTOZSB(zp); + zilog_t *zilog = zsb->z_log; ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); dmu_tx_t *tx; int error; @@ -2050,7 +2048,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))) return (error); - error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp, + error = zfs_vsec_2_aclp(zsb, ZTOI(zp)->i_mode, vsecp, cr, &fuidp, &aclp); if (error) return (error); @@ -2067,13 +2065,13 @@ top: mutex_enter(&zp->z_acl_lock); mutex_enter(&zp->z_lock); - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); /* * If old version and ACL won't fit in bonus and we aren't @@ -2081,7 +2079,7 @@ top: */ if ((acl_obj = zfs_external_acl(zp)) != 0) { - if (zfsvfs->z_version >= ZPL_VERSION_FUID && + if (zsb->z_version >= ZPL_VERSION_FUID && zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) { dmu_tx_hold_free(tx, acl_obj, 0, DMU_OBJECT_END); @@ -2116,7 +2114,7 @@ top: zp->z_acl_cached = aclp; if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); zfs_log_acl(zilog, tx, zp, vsecp, fuidp); @@ -2139,9 +2137,9 @@ static int zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) { if ((v4_mode & WRITE_MASK) && - (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) && - (!IS_DEVVP(ZTOV(zp)) || - (IS_DEVVP(ZTOV(zp)) && (v4_mode & WRITE_MASK_ATTRS)))) { + (ZTOZSB(zp)->z_vfs->mnt_flags & MNT_READONLY) && + (!S_ISDEV(ZTOI(zp)->i_mode) || + (S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) { return (EROFS); } @@ -2149,9 +2147,9 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) * Only check for READONLY on non-directories. */ if ((v4_mode & WRITE_MASK_DATA) && - (((ZTOV(zp)->v_type != VDIR) && + ((!S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) || - (ZTOV(zp)->v_type == VDIR && + (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_IMMUTABLE)))) { return (EPERM); } @@ -2198,11 +2196,11 @@ static int zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, boolean_t anyaccess, cred_t *cr) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); zfs_acl_t *aclp; int error; uid_t uid = crgetuid(cr); - uint64_t who; + uint64_t who; uint16_t type, iflags; uint16_t entry_type; uint32_t access_mask; @@ -2231,7 +2229,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, if (!zfs_acl_valid_ace_type(type, iflags)) continue; - if (ZTOV(zp)->v_type == VDIR && (iflags & ACE_INHERIT_ONLY_ACE)) + if (S_ISDIR(ZTOI(zp)->i_mode) && + (iflags & ACE_INHERIT_ONLY_ACE)) continue; /* Skip ACE if it does not affect any AoI */ @@ -2252,7 +2251,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, who = gowner; /*FALLTHROUGH*/ case ACE_IDENTIFIER_GROUP: - checkit = zfs_groupmember(zfsvfs, who, cr); + checkit = zfs_groupmember(zsb, who, cr); break; case ACE_EVERYONE: checkit = B_TRUE; @@ -2263,7 +2262,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, if (entry_type == 0) { uid_t newid; - newid = zfs_fuid_map_id(zfsvfs, who, cr, + newid = zfs_fuid_map_id(zsb, who, cr, ZFS_ACE_USER); if (newid != IDMAP_WK_CREATOR_OWNER_UID && uid == newid) @@ -2325,8 +2324,8 @@ zfs_has_access(znode_t *zp, cred_t *cr) if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) { uid_t owner; - owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); - return (secpolicy_vnode_any_access(cr, ZTOV(zp), owner) == 0); + owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER); + return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0); } return (B_TRUE); } @@ -2335,7 +2334,7 @@ static int zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); int err; *working_mode = v4_mode; @@ -2344,7 +2343,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, /* * Short circuit empty requests */ - if (v4_mode == 0 || zfsvfs->z_replay) { + if (v4_mode == 0 || zsb->z_replay) { *working_mode = 0; return (0); } @@ -2391,7 +2390,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) return (EACCES); is_attr = ((zdp->z_pflags & ZFS_XATTR) && - (ZTOV(zdp)->v_type == VDIR)); + (S_ISDIR(ZTOI(zdp)->i_mode))); if (is_attr) goto slow; @@ -2439,9 +2438,9 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) slow: DTRACE_PROBE(zfs__fastpath__execute__access__miss); - ZFS_ENTER(zdp->z_zfsvfs); + ZFS_ENTER(ZTOZSB(zdp)); error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); - ZFS_EXIT(zdp->z_zfsvfs); + ZFS_EXIT(ZTOZSB(zdp)); return (error); } @@ -2456,13 +2455,13 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) uint32_t working_mode; int error; int is_attr; - boolean_t check_privs; + boolean_t check_privs; znode_t *xzp; - znode_t *check_zp = zp; + znode_t *check_zp = zp; mode_t needed_bits; uid_t owner; - is_attr = ((zp->z_pflags & ZFS_XATTR) && (ZTOV(zp)->v_type == VDIR)); + is_attr = ((zp->z_pflags & ZFS_XATTR) && S_ISDIR(ZTOI(zp)->i_mode)); /* * If attribute then validate against base file @@ -2471,11 +2470,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) uint64_t parent; if ((error = sa_lookup(zp->z_sa_hdl, - SA_ZPL_PARENT(zp->z_zfsvfs), &parent, + SA_ZPL_PARENT(ZTOZSB(zp)), &parent, sizeof (parent))) != 0) return (error); - if ((error = zfs_zget(zp->z_zfsvfs, + if ((error = zfs_zget(ZTOZSB(zp), parent, &xzp)) != 0) { return (error); } @@ -2497,11 +2496,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) } } - owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); + owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER); /* - * Map the bits required to the standard vnode flags VREAD|VWRITE|VEXEC - * in needed_bits. Map the bits mapped by working_mode (currently - * missing) in missing_bits. + * Map the bits required to the standard inode flags + * S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits + * mapped by working_mode (currently missing) in missing_bits. * Call secpolicy_vnode_access2() with (needed_bits & ~checkmode), * needed_bits. */ @@ -2514,24 +2513,24 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE)) - needed_bits |= VREAD; + needed_bits |= S_IRUSR; if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE)) - needed_bits |= VWRITE; + needed_bits |= S_IWUSR; if (working_mode & ACE_EXECUTE) - needed_bits |= VEXEC; + needed_bits |= S_IXUSR; if ((error = zfs_zaccess_common(check_zp, mode, &working_mode, &check_privs, skipaclchk, cr)) == 0) { if (is_attr) - VN_RELE(ZTOV(xzp)); - return (secpolicy_vnode_access2(cr, ZTOV(zp), owner, + iput(ZTOI(xzp)); + return (secpolicy_vnode_access2(cr, ZTOI(zp), owner, needed_bits, needed_bits)); } if (error && !check_privs) { if (is_attr) - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); return (error); } @@ -2556,14 +2555,14 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE)) - checkmode |= VREAD; + checkmode |= S_IRUSR; if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE)) - checkmode |= VWRITE; + checkmode |= S_IWUSR; if (working_mode & ACE_EXECUTE) - checkmode |= VEXEC; + checkmode |= S_IXUSR; - error = secpolicy_vnode_access2(cr, ZTOV(check_zp), owner, + error = secpolicy_vnode_access2(cr, ZTOI(check_zp), owner, needed_bits & ~checkmode, needed_bits); if (error == 0 && (working_mode & ACE_WRITE_OWNER)) @@ -2588,19 +2587,19 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) } } } else if (error == 0) { - error = secpolicy_vnode_access2(cr, ZTOV(zp), owner, + error = secpolicy_vnode_access2(cr, ZTOI(zp), owner, needed_bits, needed_bits); } if (is_attr) - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); return (error); } /* - * Translate traditional unix VREAD/VWRITE/VEXEC mode into + * Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into * native ACL format and call zfs_zaccess() */ int @@ -2627,10 +2626,10 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp, int error; uid_t downer; - downer = zfs_fuid_map_id(dzp->z_zfsvfs, dzp->z_uid, cr, ZFS_OWNER); + downer = zfs_fuid_map_id(ZTOZSB(dzp), dzp->z_uid, cr, ZFS_OWNER); - error = secpolicy_vnode_access2(cr, ZTOV(dzp), - downer, available_perms, VWRITE|VEXEC); + error = secpolicy_vnode_access2(cr, ZTOI(dzp), + downer, available_perms, S_IWUSR|S_IXUSR); if (error == 0) error = zfs_sticky_remove_access(dzp, zp, cr); @@ -2750,8 +2749,8 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) * Fourth row */ - available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : VWRITE; - available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : VEXEC; + available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR; + available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR; return (zfs_delete_final_check(zp, dzp, available_perms, cr)); @@ -2767,7 +2766,7 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, if (szp->z_pflags & ZFS_AV_QUARANTINED) return (EACCES); - add_perm = (ZTOV(szp)->v_type == VDIR) ? + add_perm = S_ISDIR(ZTOI(szp)->i_mode) ? ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE; /* diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c index aced2886a..f54ed1912 100644 --- a/module/zfs/zfs_dir.c +++ b/module/zfs/zfs_dir.c @@ -22,7 +22,6 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ -#ifdef HAVE_ZPL #include #include @@ -62,12 +61,12 @@ * of names after deciding which is the appropriate lookup interface. */ static int -zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact, +zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact, boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid) { int error; - if (zfsvfs->z_norm) { + if (zsb->z_norm) { matchtype_t mt = MT_FIRST; boolean_t conflict = B_FALSE; size_t bufsz = 0; @@ -83,17 +82,19 @@ zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact, * In the non-mixed case we only expect there would ever * be one match, but we need to use the normalizing lookup. */ - error = zap_lookup_norm(zfsvfs->z_os, dzp->z_id, name, 8, 1, + error = zap_lookup_norm(zsb->z_os, dzp->z_id, name, 8, 1, zoid, mt, buf, bufsz, &conflict); if (!error && deflags) *deflags = conflict ? ED_CASE_CONFLICT : 0; } else { - error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, 8, 1, zoid); + error = zap_lookup(zsb->z_os, dzp->z_id, name, 8, 1, zoid); } *zoid = ZFS_DIRENT_OBJ(*zoid); +#ifdef HAVE_DNLC if (error == ENOENT && update) - dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE); + dnlc_update(ZTOI(dzp), name, DNLC_NO_VNODE); +#endif /* HAVE_DNLC */ return (error); } @@ -137,12 +138,14 @@ int zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, int flag, int *direntflags, pathname_t *realpnp) { - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); zfs_dirlock_t *dl; boolean_t update; boolean_t exact; uint64_t zoid; +#ifdef HAVE_DNLC vnode_t *vp = NULL; +#endif /* HAVE_DNLC */ int error = 0; int cmpflags; @@ -160,7 +163,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, /* * Case sensitivity and normalization preferences are set when * the file system is created. These are stored in the - * zfsvfs->z_case and zfsvfs->z_norm fields. These choices + * zsb->z_case and zsb->z_norm fields. These choices * affect what vnodes can be cached in the DNLC, how we * perform zap lookups, and the "width" of our dirlocks. * @@ -180,8 +183,8 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, * access. */ exact = - ((zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) || - ((zfsvfs->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK)); + ((zsb->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) || + ((zsb->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK)); /* * Only look in or update the DNLC if we are looking for the @@ -193,9 +196,9 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, * Maybe can add TO-UPPERed version of name to dnlc in ci-only * case for performance improvement? */ - update = !zfsvfs->z_norm || - ((zfsvfs->z_case == ZFS_CASE_MIXED) && - !(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK)); + update = !zsb->z_norm || + ((zsb->z_case == ZFS_CASE_MIXED) && + !(zsb->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK)); /* * ZRENAMING indicates we are in a situation where we should @@ -208,7 +211,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, if (flag & ZRENAMING) cmpflags = 0; else - cmpflags = zfsvfs->z_norm; + cmpflags = zsb->z_norm; /* * Wait until there are no locks on this name. @@ -288,29 +291,34 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, * See if there's an object by this name; if so, put a hold on it. */ if (flag & ZXATTR) { - error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &zoid, + error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zsb), &zoid, sizeof (zoid)); if (error == 0) error = (zoid == 0 ? ENOENT : 0); } else { +#ifdef HAVE_DNLC if (update) - vp = dnlc_lookup(ZTOV(dzp), name); + vp = dnlc_lookup(ZTOI(dzp), name); if (vp == DNLC_NO_VNODE) { - VN_RELE(vp); + iput(vp); error = ENOENT; } else if (vp) { if (flag & ZNEW) { zfs_dirent_unlock(dl); - VN_RELE(vp); + iput(vp); return (EEXIST); } *dlpp = dl; *zpp = VTOZ(vp); return (0); } else { - error = zfs_match_find(zfsvfs, dzp, name, exact, + error = zfs_match_find(zsb, dzp, name, exact, update, direntflags, realpnp, &zoid); } +#else + error = zfs_match_find(zsb, dzp, name, exact, + update, direntflags, realpnp, &zoid); +#endif /* HAVE_DNLC */ } if (error) { if (error != ENOENT || (flag & ZEXISTS)) { @@ -322,13 +330,15 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, zfs_dirent_unlock(dl); return (EEXIST); } - error = zfs_zget(zfsvfs, zoid, zpp); + error = zfs_zget(zsb, zoid, zpp); if (error) { zfs_dirent_unlock(dl); return (error); } +#ifdef HAVE_DNLC if (!(flag & ZXATTR) && update) - dnlc_update(ZTOV(dzp), name, ZTOV(*zpp)); + dnlc_update(ZTOI(dzp), name, ZTOI(*zpp)); +#endif /* HAVE_DNLC */ } *dlpp = dl; @@ -377,7 +387,7 @@ zfs_dirent_unlock(zfs_dirlock_t *dl) * special pseudo-directory. */ int -zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, +zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags, int *deflg, pathname_t *rpnp) { zfs_dirlock_t *dl; @@ -386,31 +396,35 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, uint64_t parent; if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) { - *vpp = ZTOV(dzp); - VN_HOLD(*vpp); + *ipp = ZTOI(dzp); + igrab(*ipp); } else if (name[0] == '.' && name[1] == '.' && name[2] == 0) { - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); /* * If we are a snapshot mounted under .zfs, return * the vp for the snapshot directory. */ if ((error = sa_lookup(dzp->z_sa_hdl, - SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0) + SA_ZPL_PARENT(zsb), &parent, sizeof (parent))) != 0) return (error); - if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) { - error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, - "snapshot", vpp, NULL, 0, NULL, kcred, +#ifdef HAVE_SNAPSHOT + if (parent == dzp->z_id && zsb->z_parent != zsb) { + error = zfsctl_root_lookup(zsb->z_parent->z_ctldir, + "snapshot", ipp, NULL, 0, NULL, kcred, NULL, NULL, NULL); return (error); } +#endif /* HAVE_SNAPSHOT */ rw_enter(&dzp->z_parent_lock, RW_READER); - error = zfs_zget(zfsvfs, parent, &zp); + error = zfs_zget(zsb, parent, &zp); if (error == 0) - *vpp = ZTOV(zp); + *ipp = ZTOI(zp); rw_exit(&dzp->z_parent_lock); +#ifdef HAVE_SNAPSHOT } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { - *vpp = zfsctl_root(dzp); + *ipp = zfsctl_root(dzp); +#endif /* HAVE_SNAPSHOT */ } else { int zf; @@ -420,7 +434,7 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp); if (error == 0) { - *vpp = ZTOV(zp); + *ipp = ZTOI(zp); zfs_dirent_unlock(dl); dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */ } @@ -450,13 +464,13 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, void zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); ASSERT(zp->z_unlinked); ASSERT(zp->z_links == 0); VERIFY3U(0, ==, - zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); + zap_add_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx)); } /* @@ -464,7 +478,7 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx) * (force) umounted the file system. */ void -zfs_unlinked_drain(zfsvfs_t *zfsvfs) +zfs_unlinked_drain(zfs_sb_t *zsb) { zap_cursor_t zc; zap_attribute_t zap; @@ -475,7 +489,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs) /* * Interate over the contents of the unlinked set. */ - for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj); + for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj); zap_cursor_retrieve(&zc, &zap) == 0; zap_cursor_advance(&zc)) { @@ -483,8 +497,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs) * See what kind of object we have in list */ - error = dmu_object_info(zfsvfs->z_os, - zap.za_first_integer, &doi); + error = dmu_object_info(zsb->z_os, zap.za_first_integer, &doi); if (error != 0) continue; @@ -494,7 +507,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs) * We need to re-mark these list entries for deletion, * so we pull them back into core and set zp->z_unlinked. */ - error = zfs_zget(zfsvfs, zap.za_first_integer, &zp); + error = zfs_zget(zsb, zap.za_first_integer, &zp); /* * We may pick up znodes that are already marked for deletion. @@ -506,7 +519,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs) continue; zp->z_unlinked = B_TRUE; - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); } zap_cursor_fini(&zc); } @@ -529,35 +542,34 @@ zfs_purgedir(znode_t *dzp) zap_attribute_t zap; znode_t *xzp; dmu_tx_t *tx; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); zfs_dirlock_t dl; int skipped = 0; int error; - for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id); + for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id); (error = zap_cursor_retrieve(&zc, &zap)) == 0; zap_cursor_advance(&zc)) { - error = zfs_zget(zfsvfs, + error = zfs_zget(zsb, ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp); if (error) { skipped += 1; continue; } - ASSERT((ZTOV(xzp)->v_type == VREG) || - (ZTOV(xzp)->v_type == VLNK)); + ASSERT(S_ISREG(ZTOI(xzp)->i_mode)||S_ISLNK(ZTOI(xzp)->i_mode)); - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE); dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name); dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE); - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL); /* Is this really needed ? */ zfs_sa_upgrade_txholds(tx, xzp); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { dmu_tx_abort(tx); - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); skipped += 1; continue; } @@ -570,7 +582,7 @@ zfs_purgedir(znode_t *dzp) skipped += 1; dmu_tx_commit(tx); - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); } zap_cursor_fini(&zc); if (error != ENOENT) @@ -581,8 +593,8 @@ zfs_purgedir(znode_t *dzp) void zfs_rmnode(znode_t *zp) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - objset_t *os = zfsvfs->z_os; + zfs_sb_t *zsb = ZTOZSB(zp); + objset_t *os = zsb->z_os; znode_t *xzp = NULL; dmu_tx_t *tx; uint64_t acl_obj; @@ -590,19 +602,20 @@ zfs_rmnode(znode_t *zp) int error; ASSERT(zp->z_links == 0); - ASSERT(ZTOV(zp)->v_count == 0); + ASSERT(atomic_read(&ZTOI(zp)->i_count) == 0); /* * If this is an attribute directory, purge its contents. */ - if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) { + if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) { if (zfs_purgedir(zp) != 0) { /* * Not enough space to delete some xattrs. * Leave it in the unlinked set. */ zfs_znode_dmu_fini(zp); - zfs_znode_free(zp); + zfs_inode_destroy(ZTOI(zp)); + return; } } @@ -616,7 +629,7 @@ zfs_rmnode(znode_t *zp) * Not enough space. Leave the file in the unlinked set. */ zfs_znode_dmu_fini(zp); - zfs_znode_free(zp); + zfs_inode_destroy(ZTOI(zp)); return; } @@ -624,10 +637,10 @@ zfs_rmnode(znode_t *zp) * If the file has extended attributes, we're going to unlink * the xattr dir. */ - error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), + error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xattr_obj, sizeof (xattr_obj)); if (error == 0 && xattr_obj) { - error = zfs_zget(zfsvfs, xattr_obj, &xzp); + error = zfs_zget(zsb, xattr_obj, &xzp); ASSERT(error == 0); } @@ -638,9 +651,9 @@ zfs_rmnode(znode_t *zp) */ tx = dmu_tx_create(os); dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END); - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL); if (xzp) { - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, TRUE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, TRUE, NULL); dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE); } if (acl_obj) @@ -656,7 +669,7 @@ zfs_rmnode(znode_t *zp) */ dmu_tx_abort(tx); zfs_znode_dmu_fini(zp); - zfs_znode_free(zp); + zfs_inode_destroy(ZTOI(zp)); goto out; } @@ -665,7 +678,7 @@ zfs_rmnode(znode_t *zp) mutex_enter(&xzp->z_lock); xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */ xzp->z_links = 0; /* no more links to it */ - VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs), + VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb), &xzp->z_links, sizeof (xzp->z_links), tx)); mutex_exit(&xzp->z_lock); zfs_unlinked_add(xzp, tx); @@ -673,14 +686,14 @@ zfs_rmnode(znode_t *zp) /* Remove this znode from the unlinked set */ VERIFY3U(0, ==, - zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); + zap_remove_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx)); zfs_znode_delete(zp, tx); dmu_tx_commit(tx); out: if (xzp) - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); } static uint64_t @@ -688,7 +701,7 @@ zfs_dirent(znode_t *zp, uint64_t mode) { uint64_t de = zp->z_id; - if (zp->z_zfsvfs->z_version >= ZPL_VERSION_DIRENT_TYPE) + if (ZTOZSB(zp)->z_version >= ZPL_VERSION_DIRENT_TYPE) de |= IFTODT(mode) << 60; return (de); } @@ -700,10 +713,9 @@ int zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) { znode_t *dzp = dl->dl_dzp; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - vnode_t *vp = ZTOV(zp); + zfs_sb_t *zsb = ZTOZSB(zp); uint64_t value; - int zp_is_dir = (vp->v_type == VDIR); + int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode); sa_bulk_attr_t bulk[5]; uint64_t mtime[2], ctime[2]; int count = 0; @@ -718,17 +730,17 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) return (ENOENT); } zp->z_links++; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, sizeof (zp->z_links)); } - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &dzp->z_id, sizeof (dzp->z_id)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, sizeof (zp->z_pflags)); if (!(flag & ZNEW)) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, ctime, sizeof (ctime)); zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime, B_TRUE); @@ -742,15 +754,15 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) dzp->z_size++; dzp->z_links += zp_is_dir; count = 0; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &dzp->z_size, sizeof (dzp->z_size)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &dzp->z_links, sizeof (dzp->z_links)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, sizeof (mtime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, ctime, sizeof (ctime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &dzp->z_pflags, sizeof (dzp->z_pflags)); zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx); @@ -758,11 +770,13 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) mutex_exit(&dzp->z_lock); value = zfs_dirent(zp, zp->z_mode); - error = zap_add(zp->z_zfsvfs->z_os, dzp->z_id, dl->dl_name, + error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, 8, 1, &value, tx); ASSERT(error == 0); - dnlc_update(ZTOV(dzp), dl->dl_name, vp); +#ifdef HAVE_DNLC + dnlc_update(ZTOI(dzp), dl->dl_name, vp); +#endif /* HAVE_DNLC */ return (0); } @@ -773,18 +787,18 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx, { int error; - if (zp->z_zfsvfs->z_norm) { - if (((zp->z_zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && + if (ZTOZSB(zp)->z_norm) { + if (((ZTOZSB(zp)->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) || - ((zp->z_zfsvfs->z_case == ZFS_CASE_MIXED) && + ((ZTOZSB(zp)->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK))) - error = zap_remove_norm(zp->z_zfsvfs->z_os, + error = zap_remove_norm(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, MT_EXACT, tx); else - error = zap_remove_norm(zp->z_zfsvfs->z_os, + error = zap_remove_norm(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, MT_FIRST, tx); } else { - error = zap_remove(zp->z_zfsvfs->z_os, + error = zap_remove(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, tx); } @@ -803,31 +817,23 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag, boolean_t *unlinkedp) { znode_t *dzp = dl->dl_dzp; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; - vnode_t *vp = ZTOV(zp); - int zp_is_dir = (vp->v_type == VDIR); + zfs_sb_t *zsb = ZTOZSB(dzp); + int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode); boolean_t unlinked = B_FALSE; sa_bulk_attr_t bulk[5]; uint64_t mtime[2], ctime[2]; int count = 0; int error; - dnlc_remove(ZTOV(dzp), dl->dl_name); +#ifdef HAVE_DNLC + dnlc_remove(ZTOI(dzp), dl->dl_name); +#endif /* HAVE_DNLC */ if (!(flag & ZRENAMING)) { - if (vn_vfswlock(vp)) /* prevent new mounts on zp */ - return (EBUSY); - - if (vn_ismntpt(vp)) { /* don't remove mount point */ - vn_vfsunlock(vp); - return (EBUSY); - } - mutex_enter(&zp->z_lock); if (zp_is_dir && !zfs_dirempty(zp)) { mutex_exit(&zp->z_lock); - vn_vfsunlock(vp); return (EEXIST); } @@ -839,16 +845,13 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag, error = zfs_dropname(dl, zp, dzp, tx, flag); if (error != 0) { mutex_exit(&zp->z_lock); - vn_vfsunlock(vp); return (error); } if (zp->z_links <= zp_is_dir) { - zfs_panic_recover("zfs: link count on %s is %u, " - "should be at least %u", - zp->z_vnode->v_path ? zp->z_vnode->v_path : - "", (int)zp->z_links, - zp_is_dir + 1); + zfs_panic_recover("zfs: link count on %lu is %u, " + "should be at least %u", zp->z_id, + (int)zp->z_links, zp_is_dir + 1); zp->z_links = zp_is_dir + 1; } if (--zp->z_links == zp_is_dir) { @@ -856,20 +859,19 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag, zp->z_links = 0; unlinked = B_TRUE; } else { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, sizeof (ctime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, sizeof (zp->z_pflags)); zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime, B_TRUE); } - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, sizeof (zp->z_links)); error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); count = 0; ASSERT(error == 0); mutex_exit(&zp->z_lock); - vn_vfsunlock(vp); } else { error = zfs_dropname(dl, zp, dzp, tx, flag); if (error != 0) @@ -879,15 +881,15 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag, mutex_enter(&dzp->z_lock); dzp->z_size--; /* one dirent removed */ dzp->z_links -= zp_is_dir; /* ".." link from zp */ - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &dzp->z_links, sizeof (dzp->z_links)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &dzp->z_size, sizeof (dzp->z_size)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, ctime, sizeof (ctime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, sizeof (mtime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &dzp->z_pflags, sizeof (dzp->z_pflags)); zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx); @@ -914,38 +916,40 @@ zfs_dirempty(znode_t *dzp) } int -zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr) +zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); znode_t *xzp; dmu_tx_t *tx; int error; zfs_acl_ids_t acl_ids; boolean_t fuid_dirtied; +#ifdef DEBUG uint64_t parent; +#endif - *xvpp = NULL; + *xipp = NULL; - if (error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)) + if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr))) return (error); if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL, &acl_ids)) != 0) return (error); - if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { + if (zfs_acl_ids_overquota(zsb, &acl_ids)) { zfs_acl_ids_free(&acl_ids); return (EDQUOT); } top: - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes + ZFS_SA_BASE_ATTR_SIZE); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); error = dmu_tx_assign(tx, TXG_NOWAIT); if (error) { if (error == ERESTART) { @@ -960,24 +964,24 @@ top: zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids); if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); #ifdef DEBUG - error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), + error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zsb), &parent, sizeof (parent)); ASSERT(error == 0 && parent == zp->z_id); #endif - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id, + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xzp->z_id, sizeof (xzp->z_id), tx)); - (void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, + (void) zfs_log_create(zsb->z_log, tx, TX_MKXATTR, zp, xzp, "", NULL, acl_ids.z_fuidp, vap); zfs_acl_ids_free(&acl_ids); dmu_tx_commit(tx); - *xvpp = ZTOV(xzp); + *xipp = ZTOI(xzp); return (0); } @@ -990,15 +994,15 @@ top: * cr - credentials of caller * flags - flags from the VOP_LOOKUP call * - * OUT: xzpp - pointer to extended attribute znode + * OUT: xipp - pointer to extended attribute znode * * RETURN: 0 on success * error number on failure */ int -zfs_get_xattrdir(znode_t *zp, vnode_t **xvpp, cred_t *cr, int flags) +zfs_get_xattrdir(znode_t *zp, struct inode **xipp, cred_t *cr, int flags) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); znode_t *xzp; zfs_dirlock_t *dl; vattr_t va; @@ -1009,18 +1013,17 @@ top: return (error); if (xzp != NULL) { - *xvpp = ZTOV(xzp); + *xipp = ZTOI(xzp); zfs_dirent_unlock(dl); return (0); } - if (!(flags & CREATE_XATTR_DIR)) { zfs_dirent_unlock(dl); return (ENOENT); } - if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { + if (zsb->z_vfs->mnt_flags & MNT_READONLY) { zfs_dirent_unlock(dl); return (EROFS); } @@ -1035,12 +1038,11 @@ top: * Once in a directory the ability to read/write attributes * is controlled by the permissions on the attribute file. */ - va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID; - va.va_type = VDIR; + va.va_mask = ATTR_MODE | ATTR_UID | ATTR_GID; va.va_mode = S_IFDIR | S_ISVTX | 0777; zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid); - error = zfs_make_xattrdir(zp, &va, xvpp, cr); + error = zfs_make_xattrdir(zp, &va, xipp, cr); zfs_dirent_unlock(dl); if (error == ERESTART) { @@ -1067,25 +1069,24 @@ top: int zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr) { - uid_t uid; + uid_t uid; uid_t downer; uid_t fowner; - zfsvfs_t *zfsvfs = zdp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zdp); - if (zdp->z_zfsvfs->z_replay) + if (zsb->z_replay) return (0); if ((zdp->z_mode & S_ISVTX) == 0) return (0); - downer = zfs_fuid_map_id(zfsvfs, zdp->z_uid, cr, ZFS_OWNER); - fowner = zfs_fuid_map_id(zfsvfs, zp->z_uid, cr, ZFS_OWNER); + downer = zfs_fuid_map_id(zsb, zdp->z_uid, cr, ZFS_OWNER); + fowner = zfs_fuid_map_id(zsb, zp->z_uid, cr, ZFS_OWNER); if ((uid = crgetuid(cr)) == downer || uid == fowner || - (ZTOV(zp)->v_type == VREG && + (S_ISDIR(ZTOI(zp)->i_mode) && zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)) return (0); else return (secpolicy_vnode_remove(cr)); } -#endif /* HAVE_ZPL */ diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index a5741185a..f1e071fc7 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -46,7 +46,7 @@ * two AVL trees are created. One tree is keyed by the index number * and the other by the domain string. Nodes are never removed from * trees, but new entries may be added. If a new entry is added then - * the zfsvfs->z_fuid_dirty flag is set to true and the caller will then + * the zsb->z_fuid_dirty flag is set to true and the caller will then * be responsible for calling zfs_fuid_sync() to sync the changes to disk. * */ @@ -196,34 +196,34 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx) * Load the fuid table(s) into memory. */ static void -zfs_fuid_init(zfsvfs_t *zfsvfs) +zfs_fuid_init(zfs_sb_t *zsb) { - rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); + rw_enter(&zsb->z_fuid_lock, RW_WRITER); - if (zfsvfs->z_fuid_loaded) { - rw_exit(&zfsvfs->z_fuid_lock); + if (zsb->z_fuid_loaded) { + rw_exit(&zsb->z_fuid_lock); return; } - zfs_fuid_avl_tree_create(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain); + zfs_fuid_avl_tree_create(&zsb->z_fuid_idx, &zsb->z_fuid_domain); - (void) zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, - ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj); - if (zfsvfs->z_fuid_obj != 0) { - zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os, - zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, - &zfsvfs->z_fuid_domain); + (void) zap_lookup(zsb->z_os, MASTER_NODE_OBJ, + ZFS_FUID_TABLES, 8, 1, &zsb->z_fuid_obj); + if (zsb->z_fuid_obj != 0) { + zsb->z_fuid_size = zfs_fuid_table_load(zsb->z_os, + zsb->z_fuid_obj, &zsb->z_fuid_idx, + &zsb->z_fuid_domain); } - zfsvfs->z_fuid_loaded = B_TRUE; - rw_exit(&zfsvfs->z_fuid_lock); + zsb->z_fuid_loaded = B_TRUE; + rw_exit(&zsb->z_fuid_lock); } /* * sync out AVL trees to persistent storage. */ void -zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx) +zfs_fuid_sync(zfs_sb_t *zsb, dmu_tx_t *tx) { nvlist_t *nvp; nvlist_t **fuids; @@ -234,30 +234,30 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx) int numnodes; int i; - if (!zfsvfs->z_fuid_dirty) { + if (!zsb->z_fuid_dirty) { return; } - rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); + rw_enter(&zsb->z_fuid_lock, RW_WRITER); /* * First see if table needs to be created? */ - if (zfsvfs->z_fuid_obj == 0) { - zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os, + if (zsb->z_fuid_obj == 0) { + zsb->z_fuid_obj = dmu_object_alloc(zsb->z_os, DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE, sizeof (uint64_t), tx); - VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, + VERIFY(zap_add(zsb->z_os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, sizeof (uint64_t), 1, - &zfsvfs->z_fuid_obj, tx) == 0); + &zsb->z_fuid_obj, tx) == 0); } VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0); - numnodes = avl_numnodes(&zfsvfs->z_fuid_idx); + numnodes = avl_numnodes(&zsb->z_fuid_idx); fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP); - for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++, - domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) { + for (i = 0, domnode = avl_first(&zsb->z_fuid_domain); domnode; i++, + domnode = AVL_NEXT(&zsb->z_fuid_domain, domnode)) { VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX, domnode->f_idx) == 0); @@ -275,30 +275,29 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx) VERIFY(nvlist_pack(nvp, &packed, &nvsize, NV_ENCODE_XDR, KM_SLEEP) == 0); nvlist_free(nvp); - zfsvfs->z_fuid_size = nvsize; - dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, - zfsvfs->z_fuid_size, packed, tx); - kmem_free(packed, zfsvfs->z_fuid_size); - VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj, + zsb->z_fuid_size = nvsize; + dmu_write(zsb->z_os, zsb->z_fuid_obj, 0, zsb->z_fuid_size, packed, tx); + kmem_free(packed, zsb->z_fuid_size); + VERIFY(0 == dmu_bonus_hold(zsb->z_os, zsb->z_fuid_obj, FTAG, &db)); dmu_buf_will_dirty(db, tx); - *(uint64_t *)db->db_data = zfsvfs->z_fuid_size; + *(uint64_t *)db->db_data = zsb->z_fuid_size; dmu_buf_rele(db, FTAG); - zfsvfs->z_fuid_dirty = B_FALSE; - rw_exit(&zfsvfs->z_fuid_lock); + zsb->z_fuid_dirty = B_FALSE; + rw_exit(&zsb->z_fuid_lock); } /* * Query domain table for a given domain. * * If domain isn't found and addok is set, it is added to AVL trees and - * the zfsvfs->z_fuid_dirty flag will be set to TRUE. It will then be + * the zsb->z_fuid_dirty flag will be set to TRUE. It will then be * necessary for the caller or another thread to detect the dirty table * and sync out the changes. */ int -zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, +zfs_fuid_find_by_domain(zfs_sb_t *zsb, const char *domain, char **retdomain, boolean_t addok) { fuid_domain_t searchnode, *findnode; @@ -319,23 +318,23 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, searchnode.f_ksid = ksid_lookupdomain(domain); if (retdomain) *retdomain = searchnode.f_ksid->kd_name; - if (!zfsvfs->z_fuid_loaded) - zfs_fuid_init(zfsvfs); + if (!zsb->z_fuid_loaded) + zfs_fuid_init(zsb); retry: - rw_enter(&zfsvfs->z_fuid_lock, rw); - findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc); + rw_enter(&zsb->z_fuid_lock, rw); + findnode = avl_find(&zsb->z_fuid_domain, &searchnode, &loc); if (findnode) { - rw_exit(&zfsvfs->z_fuid_lock); + rw_exit(&zsb->z_fuid_lock); ksiddomain_rele(searchnode.f_ksid); return (findnode->f_idx); } else if (addok) { fuid_domain_t *domnode; uint64_t retidx; - if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) { - rw_exit(&zfsvfs->z_fuid_lock); + if (rw == RW_READER && !rw_tryupgrade(&zsb->z_fuid_lock)) { + rw_exit(&zsb->z_fuid_lock); rw = RW_WRITER; goto retry; } @@ -343,15 +342,15 @@ retry: domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP); domnode->f_ksid = searchnode.f_ksid; - retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1; + retidx = domnode->f_idx = avl_numnodes(&zsb->z_fuid_idx) + 1; - avl_add(&zfsvfs->z_fuid_domain, domnode); - avl_add(&zfsvfs->z_fuid_idx, domnode); - zfsvfs->z_fuid_dirty = B_TRUE; - rw_exit(&zfsvfs->z_fuid_lock); + avl_add(&zsb->z_fuid_domain, domnode); + avl_add(&zsb->z_fuid_idx, domnode); + zsb->z_fuid_dirty = B_TRUE; + rw_exit(&zsb->z_fuid_lock); return (retidx); } else { - rw_exit(&zfsvfs->z_fuid_lock); + rw_exit(&zsb->z_fuid_lock); return (-1); } } @@ -363,23 +362,23 @@ retry: * */ const char * -zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) +zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx) { char *domain; - if (idx == 0 || !zfsvfs->z_use_fuids) + if (idx == 0 || !zsb->z_use_fuids) return (NULL); - if (!zfsvfs->z_fuid_loaded) - zfs_fuid_init(zfsvfs); + if (!zsb->z_fuid_loaded) + zfs_fuid_init(zsb); - rw_enter(&zfsvfs->z_fuid_lock, RW_READER); + rw_enter(&zsb->z_fuid_lock, RW_READER); - if (zfsvfs->z_fuid_obj || zfsvfs->z_fuid_dirty) - domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx); + if (zsb->z_fuid_obj || zsb->z_fuid_dirty) + domain = zfs_fuid_idx_domain(&zsb->z_fuid_idx, idx); else domain = nulldomain; - rw_exit(&zfsvfs->z_fuid_lock); + rw_exit(&zsb->z_fuid_lock); ASSERT(domain); return (domain); @@ -388,12 +387,12 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) void zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp) { - *uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); - *gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_gid, cr, ZFS_GROUP); + *uidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER); + *gidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_gid, cr, ZFS_GROUP); } uid_t -zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, +zfs_fuid_map_id(zfs_sb_t *zsb, uint64_t fuid, cred_t *cr, zfs_fuid_type_t type) { #ifdef HAVE_KSID @@ -404,7 +403,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, if (index == 0) return (fuid); - domain = zfs_fuid_find_by_idx(zfsvfs, index); + domain = zfs_fuid_find_by_idx(zsb, index); ASSERT(domain != NULL); if (type == ZFS_OWNER || type == ZFS_ACE_USER) { @@ -499,13 +498,13 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid, * be used if it exists. */ uint64_t -zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, +zfs_fuid_create_cred(zfs_sb_t *zsb, zfs_fuid_type_t type, cred_t *cr, zfs_fuid_info_t **fuidp) { uint64_t idx; ksid_t *ksid; uint32_t rid; - char *kdomain; + char *kdomain; const char *domain; uid_t id; @@ -513,7 +512,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP); - if (!zfsvfs->z_use_fuids || (ksid == NULL)) { + if (!zsb->z_use_fuids || (ksid == NULL)) { id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr); if (IS_EPHEMERAL(id)) @@ -536,7 +535,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, rid = ksid_getrid(ksid); domain = ksid_getdomain(ksid); - idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE); + idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE); zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type); @@ -554,10 +553,10 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, * * During replay operations the domain+rid information is * found in the zfs_fuid_info_t that the replay code has - * attached to the zfsvfs of the file system. + * attached to the zsb of the file system. */ uint64_t -zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, +zfs_fuid_create(zfs_sb_t *zsb, uint64_t id, cred_t *cr, zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp) { #ifdef HAVE_KSID @@ -578,11 +577,11 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, * chmod. */ - if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0) + if (!zsb->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0) return (id); - if (zfsvfs->z_replay) { - fuidp = zfsvfs->z_fuid_replay; + if (zsb->z_replay) { + fuidp = zsb->z_fuid_replay; /* * If we are passed an ephemeral id, but no @@ -629,9 +628,9 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, } } - idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE); + idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE); - if (!zfsvfs->z_replay) + if (!zsb->z_replay) zfs_fuid_node_add(fuidpp, kdomain, rid, idx, id, type); else if (zfuid != NULL) { @@ -648,15 +647,15 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, } void -zfs_fuid_destroy(zfsvfs_t *zfsvfs) +zfs_fuid_destroy(zfs_sb_t *zsb) { - rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); - if (!zfsvfs->z_fuid_loaded) { - rw_exit(&zfsvfs->z_fuid_lock); + rw_enter(&zsb->z_fuid_lock, RW_WRITER); + if (!zsb->z_fuid_loaded) { + rw_exit(&zsb->z_fuid_lock); return; } - zfs_fuid_table_destroy(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain); - rw_exit(&zfsvfs->z_fuid_lock); + zfs_fuid_table_destroy(&zsb->z_fuid_idx, &zsb->z_fuid_domain); + rw_exit(&zsb->z_fuid_lock); } /* @@ -710,7 +709,7 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp) * Will use a straight FUID compare when possible. */ boolean_t -zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) +zfs_groupmember(zfs_sb_t *zsb, uint64_t id, cred_t *cr) { #ifdef HAVE_KSID ksid_t *ksid = crgetsid(cr, KSID_GROUP); @@ -718,7 +717,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) uid_t gid; if (ksid && ksidlist) { - int i; + int i; ksid_t *ksid_groups; uint32_t idx = FUID_INDEX(id); uint32_t rid = FUID_RID(id); @@ -734,7 +733,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) } else { const char *domain; - domain = zfs_fuid_find_by_idx(zfsvfs, idx); + domain = zfs_fuid_find_by_idx(zsb, idx); ASSERT(domain != NULL); if (strcmp(domain, @@ -752,7 +751,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) /* * Not found in ksidlist, check posix groups */ - gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP); + gid = zfs_fuid_map_id(zsb, id, cr, ZFS_GROUP); return (groupmember(gid, cr)); #else return (B_TRUE); @@ -760,17 +759,17 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) } void -zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx) +zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx) { - if (zfsvfs->z_fuid_obj == 0) { + if (zsb->z_fuid_obj == 0) { dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - FUID_SIZE_ESTIMATE(zfsvfs)); + FUID_SIZE_ESTIMATE(zsb)); dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); } else { - dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); - dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, - FUID_SIZE_ESTIMATE(zfsvfs)); + dmu_tx_hold_bonus(tx, zsb->z_fuid_obj); + dmu_tx_hold_write(tx, zsb->z_fuid_obj, 0, + FUID_SIZE_ESTIMATE(zsb)); } } #endif diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 593ed74bb..994d65f7e 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -432,7 +432,7 @@ zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr) /* * If the existing dataset label is nondefault, check if the * dataset is mounted (label cannot be changed while mounted). - * Get the zfsvfs; if there isn't one, then the dataset isn't + * Get the zfs_sb_t; if there isn't one, then the dataset isn't * mounted (or isn't a dataset, doesn't exist, ...). */ if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) { @@ -849,20 +849,6 @@ zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr) return (error); } -#ifdef HAVE_ZPL -static int -zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr) -{ - int error; - - error = secpolicy_fs_unmount(cr, NULL); - if (error) { - error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr); - } - return (error); -} -#endif /* HAVE_ZPL */ - /* * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires * SYS_CONFIG privilege, which is not available in a local zone. @@ -1105,9 +1091,8 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) return (error); } -#ifdef HAVE_ZPL static int -getzfsvfs(const char *dsname, zfsvfs_t **zfvp) +get_zfs_sb(const char *dsname, zfs_sb_t **zsbp) { objset_t *os; int error; @@ -1121,9 +1106,9 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp) } mutex_enter(&os->os_user_ptr_lock); - *zfvp = dmu_objset_get_user(os); - if (*zfvp) { - VFS_HOLD((*zfvp)->z_vfs); + *zsbp = dmu_objset_get_user(os); + if (*zsbp) { + mntget((*zsbp)->z_vfs); } else { error = ESRCH; } @@ -1131,52 +1116,45 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp) dmu_objset_rele(os, FTAG); return (error); } -#endif /* - * Find a zfsvfs_t for a mounted filesystem, or create our own, in which + * Find a zfs_sb_t for a mounted filesystem, or create our own, in which * case its z_vfs will be NULL, and it will be opened as the owner. */ static int -zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer) +zfs_sb_hold(const char *name, void *tag, zfs_sb_t **zsbp, boolean_t writer) { -#ifdef HAVE_ZPL int error = 0; - if (getzfsvfs(name, zfvp) != 0) - error = zfsvfs_create(name, zfvp); + if (get_zfs_sb(name, zsbp) != 0) + error = zfs_sb_create(name, zsbp); if (error == 0) { - rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER : + rrw_enter(&(*zsbp)->z_teardown_lock, (writer) ? RW_WRITER : RW_READER, tag); - if ((*zfvp)->z_unmounted) { + if ((*zsbp)->z_unmounted) { /* * XXX we could probably try again, since the unmounting * thread should be just about to disassociate the * objset from the zfsvfs. */ - rrw_exit(&(*zfvp)->z_teardown_lock, tag); + rrw_exit(&(*zsbp)->z_teardown_lock, tag); return (EBUSY); } } return (error); -#else - return ENOTSUP; -#endif } static void -zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag) +zfs_sb_rele(zfs_sb_t *zsb, void *tag) { -#ifdef HAVE_ZPL - rrw_exit(&zfsvfs->z_teardown_lock, tag); + rrw_exit(&zsb->z_teardown_lock, tag); - if (zfsvfs->z_vfs) { - VFS_RELE(zfsvfs->z_vfs); + if (zsb->z_vfs) { + mntput(zsb->z_vfs); } else { - dmu_objset_disown(zfsvfs->z_os, zfsvfs); - zfsvfs_free(zfsvfs); + dmu_objset_disown(zsb->z_os, zsb); + zfs_sb_free(zsb); } -#endif } static int @@ -2086,7 +2064,6 @@ top: static int zfs_prop_set_userquota(const char *dsname, nvpair_t *pair) { -#ifdef HAVE_ZPL const char *propname = nvpair_name(pair); uint64_t *valary; unsigned int vallen; @@ -2095,7 +2072,7 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair) zfs_userquota_prop_t type; uint64_t rid; uint64_t quota; - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; int err; if (nvpair_type(pair) == DATA_TYPE_NVLIST) { @@ -2120,16 +2097,13 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair) rid = valary[1]; quota = valary[2]; - err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE); + err = zfs_sb_hold(dsname, FTAG, &zsb, B_FALSE); if (err == 0) { - err = zfs_set_userquota(zfsvfs, type, domain, rid, quota); - zfsvfs_rele(zfsvfs, FTAG); + err = zfs_set_userquota(zsb, type, domain, rid, quota); + zfs_sb_rele(zsb, FTAG); } return (err); -#else - return ENOTSUP; -#endif } /* @@ -2185,15 +2159,13 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, break; case ZFS_PROP_VERSION: { - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; - if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0) + if ((err = zfs_sb_hold(dsname, FTAG, &zsb, B_TRUE)) != 0) break; -#ifdef HAVE_ZPL - err = zfs_set_version(zfsvfs, intval); -#endif - zfsvfs_rele(zfsvfs, FTAG); + err = zfs_set_version(zsb, intval); + zfs_sb_rele(zsb, FTAG); if (err == 0 && intval >= ZPL_VERSION_USERSPACE) { zfs_cmd_t *zc; @@ -2748,7 +2720,7 @@ zfs_ioc_get_fsacl(zfs_cmd_t *zc) return (error); } -#ifdef HAVE_ZPL +#ifdef HAVE_SNAPSHOT /* * Search the vfs list for a specified resource. Returns a pointer to it * or NULL if no suitable entry is found. The caller of this routine @@ -2764,7 +2736,7 @@ zfs_get_vfs(const char *resource) vfsp = rootvfs; do { if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { - VFS_HOLD(vfsp); + mntget(vfsp); vfs_found = vfsp; break; } @@ -2773,7 +2745,7 @@ zfs_get_vfs(const char *resource) vfs_list_unlock(); return (vfs_found); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_SNAPSHOT */ /* ARGSUSED */ static void @@ -3128,7 +3100,7 @@ out: int zfs_unmount_snap(const char *name, void *arg) { -#ifdef HAVE_ZPL +#ifdef HAVE_SNAPSHOT vfs_t *vfsp = NULL; if (arg) { @@ -3148,14 +3120,14 @@ zfs_unmount_snap(const char *name, void *arg) int err; if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) { - VFS_RELE(vfsp); + mntput(vfsp); return (err); } - VFS_RELE(vfsp); + mntput(vfsp); if ((err = dounmount(vfsp, flag, kcred)) != 0) return (err); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_SNAPSHOT */ return (0); } @@ -3215,10 +3187,9 @@ zfs_ioc_destroy(zfs_cmd_t *zc) static int zfs_ioc_rollback(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL dsl_dataset_t *ds, *clone; int error; - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; char *clone_name; error = dsl_dataset_hold(zc->zc_name, FTAG, &ds); @@ -3252,8 +3223,8 @@ zfs_ioc_rollback(zfs_cmd_t *zc) /* * Do clone swap. */ - if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { - error = zfs_suspend_fs(zfsvfs); + if (get_zfs_sb(zc->zc_name, &zsb) == 0) { + error = zfs_suspend_fs(zsb); if (error == 0) { int resume_err; @@ -3265,10 +3236,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc) } else { error = EBUSY; } - resume_err = zfs_resume_fs(zfsvfs, zc->zc_name); + resume_err = zfs_resume_fs(zsb, zc->zc_name); error = error ? error : resume_err; } - VFS_RELE(zfsvfs->z_vfs); + mntput(zsb->z_vfs); } else { if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { error = dsl_dataset_clone_swap(clone, ds, B_TRUE); @@ -3289,9 +3260,6 @@ out: if (ds) dsl_dataset_rele(ds, FTAG); return (error); -#else - return (ENOTSUP); -#endif /* HAVE_ZPL */ } /* @@ -3741,29 +3709,25 @@ zfs_ioc_recv(zfs_cmd_t *zc) &zc->zc_action_handle); if (error == 0) { -#ifdef HAVE_ZPL - zfsvfs_t *zfsvfs = NULL; + zfs_sb_t *zsb = NULL; - if (getzfsvfs(tofs, &zfsvfs) == 0) { + if (get_zfs_sb(tofs, &zsb) == 0) { /* online recv */ int end_err; - error = zfs_suspend_fs(zfsvfs); + error = zfs_suspend_fs(zsb); /* * If the suspend fails, then the recv_end will * likely also fail, and clean up after itself. */ end_err = dmu_recv_end(&drc); if (error == 0) - error = zfs_resume_fs(zfsvfs, tofs); + error = zfs_resume_fs(zsb, tofs); error = error ? error : end_err; - VFS_RELE(zfsvfs->z_vfs); + mntput(zsb->z_vfs); } else { error = dmu_recv_end(&drc); } -#else - error = dmu_recv_end(&drc); -#endif /* HAVE_ZPL */ } zc->zc_cookie = off - fp->f_offset; @@ -4087,25 +4051,21 @@ zfs_ioc_promote(zfs_cmd_t *zc) static int zfs_ioc_userspace_one(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; int error; if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) return (EINVAL); - error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); + error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE); if (error) return (error); - error = zfs_userspace_one(zfsvfs, + error = zfs_userspace_one(zsb, zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie); - zfsvfs_rele(zfsvfs, FTAG); + zfs_sb_rele(zsb, FTAG); return (error); -#else - return (ENOTSUP); -#endif /* HAVE_ZPL */ } /* @@ -4122,20 +4082,21 @@ zfs_ioc_userspace_one(zfs_cmd_t *zc) static int zfs_ioc_userspace_many(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; int bufsize = zc->zc_nvlist_dst_size; + int error; + void *buf; if (bufsize <= 0) return (ENOMEM); - int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); + error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE); if (error) return (error); - void *buf = kmem_alloc(bufsize, KM_SLEEP); + buf = kmem_alloc(bufsize, KM_SLEEP); - error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie, + error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie, buf, &zc->zc_nvlist_dst_size); if (error == 0) { @@ -4144,12 +4105,9 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc) zc->zc_nvlist_dst_size); } kmem_free(buf, bufsize); - zfsvfs_rele(zfsvfs, FTAG); + zfs_sb_rele(zsb, FTAG); return (error); -#else - return (ENOTSUP); -#endif /* HAVE_ZPL */ } /* @@ -4162,25 +4120,24 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc) static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) { -#ifdef HAVE_ZPL objset_t *os; int error = 0; - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; - if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { - if (!dmu_objset_userused_enabled(zfsvfs->z_os)) { + if (get_zfs_sb(zc->zc_name, &zsb) == 0) { + if (!dmu_objset_userused_enabled(zsb->z_os)) { /* * If userused is not enabled, it may be because the * objset needs to be closed & reopened (to grow the * objset_phys_t). Suspend/resume the fs will do that. */ - error = zfs_suspend_fs(zfsvfs); + error = zfs_suspend_fs(zsb); if (error == 0) - error = zfs_resume_fs(zfsvfs, zc->zc_name); + error = zfs_resume_fs(zsb, zc->zc_name); } if (error == 0) - error = dmu_objset_userspace_upgrade(zfsvfs->z_os); - VFS_RELE(zfsvfs->z_vfs); + error = dmu_objset_userspace_upgrade(zsb->z_os); + mntput(zsb->z_vfs); } else { /* XXX kind of reading contents without owning */ error = dmu_objset_hold(zc->zc_name, FTAG, &os); @@ -4192,9 +4149,6 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) } return (error); -#else - return (ENOTSUP); -#endif /* HAVE_ZPL */ } /* @@ -4456,10 +4410,10 @@ zfs_smb_acl_purge(znode_t *dzp) { zap_cursor_t zc; zap_attribute_t zap; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); int error; - for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id); + for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id); (error = zap_cursor_retrieve(&zc, &zap)) == 0; zap_cursor_advance(&zc)) { if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred, @@ -4479,7 +4433,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) znode_t *dzp; vnode_t *resourcevp = NULL; znode_t *sharedir; - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; nvlist_t *nvlist; char *src, *target; vattr_t vattr; @@ -4500,17 +4454,17 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) } dzp = VTOZ(vp); - zfsvfs = dzp->z_zfsvfs; - ZFS_ENTER(zfsvfs); + zsb = ZTOZSB(dzp); + ZFS_ENTER(zsb); /* * Create share dir if its missing. */ - mutex_enter(&zfsvfs->z_lock); - if (zfsvfs->z_shares_dir == 0) { + mutex_enter(&zsb->z_lock); + if (zsb->z_shares_dir == 0) { dmu_tx_t *tx; - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE, ZFS_SHARES_DIR); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); @@ -4518,29 +4472,28 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) if (error) { dmu_tx_abort(tx); } else { - error = zfs_create_share_dir(zfsvfs, tx); + error = zfs_create_share_dir(zsb, tx); dmu_tx_commit(tx); } if (error) { - mutex_exit(&zfsvfs->z_lock); + mutex_exit(&zsb->z_lock); VN_RELE(vp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } } - mutex_exit(&zfsvfs->z_lock); + mutex_exit(&zsb->z_lock); - ASSERT(zfsvfs->z_shares_dir); - if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) { + ASSERT(zsb->z_shares_dir); + if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) { VN_RELE(vp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } switch (zc->zc_cookie) { case ZFS_SMB_ACL_ADD: vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; - vattr.va_type = VREG; vattr.va_mode = S_IFREG|0777; vattr.va_uid = 0; vattr.va_gid = 0; @@ -4565,7 +4518,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) { VN_RELE(vp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) || @@ -4573,7 +4526,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) &target)) { VN_RELE(vp); VN_RELE(ZTOV(sharedir)); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); nvlist_free(nvlist); return (error); } @@ -4594,7 +4547,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) VN_RELE(vp); VN_RELE(ZTOV(sharedir)); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); #else diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c index 59a6451c7..945b734ce 100644 --- a/module/zfs/zfs_log.c +++ b/module/zfs/zfs_log.c @@ -22,7 +22,6 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ -#ifdef HAVE_ZPL #include #include @@ -411,9 +410,9 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, lr->lr_uid = zp->z_uid; lr->lr_gid = zp->z_gid; lr->lr_mode = zp->z_mode; - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen, + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen, sizeof (uint64_t)); - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), lr->lr_crtime, sizeof (uint64_t) * 2); bcopy(name, (char *)(lr + 1), namesize); bcopy(link, (char *)(lr + 1) + namesize, linksize); @@ -496,7 +495,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, itx = zil_itx_create(txtype, sizeof (*lr) + (write_state == WR_COPIED ? len : 0)); lr = (lr_write_t *)&itx->itx_lr; - if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os, + if (write_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os, zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) { zil_itx_destroy(itx); itx = zil_itx_create(txtype, sizeof (*lr)); @@ -513,7 +512,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, lr->lr_blkoff = 0; BP_ZERO(&lr->lr_blkptr); - itx->itx_private = zp->z_zfsvfs; + itx->itx_private = ZTOZSB(zp); if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) && (fsync_cnt == 0)) @@ -629,7 +628,7 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, if (zil_replaying(zilog, tx) || zp->z_unlinked) return; - txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ? + txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ? TX_ACL_V0 : TX_ACL; if (txtype == TX_ACL) @@ -667,14 +666,14 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); +#ifdef HAVE_XVATTR if (fuidp) { start = zfs_log_fuid_ids(fuidp, start); (void) zfs_log_fuid_domains(fuidp, start); } +#endif /* HAVE_XVATTR */ } itx->itx_sync = (zp->z_sync_cnt != 0); zil_itx_assign(zilog, itx, tx); } - -#endif /* HAVE_ZPL */ diff --git a/module/zfs/zfs_rlock.c b/module/zfs/zfs_rlock.c index 4e3c176a3..6709ce80b 100644 --- a/module/zfs/zfs_rlock.c +++ b/module/zfs/zfs_rlock.c @@ -134,7 +134,7 @@ zfs_range_lock_writer(znode_t *zp, rl_t *new) */ end_size = MAX(zp->z_size, new->r_off + len); if (end_size > zp->z_blksz && (!ISP2(zp->z_blksz) || - zp->z_blksz < zp->z_zfsvfs->z_max_blksz)) { + zp->z_blksz < ZTOZSB(zp)->z_max_blksz)) { new->r_off = 0; new->r_len = UINT64_MAX; } diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c index 68bce0a6e..ed696490f 100644 --- a/module/zfs/zfs_sa.c +++ b/module/zfs/zfs_sa.c @@ -81,7 +81,7 @@ zfs_sa_readlink(znode_t *zp, uio_t *uio) MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); } else { dmu_buf_t *dbp; - if ((error = dmu_buf_hold(zp->z_zfsvfs->z_os, zp->z_id, + if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) { error = uiomove(dbp->db_data, MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); @@ -107,7 +107,7 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx) dmu_buf_t *dbp; zfs_grow_blocksize(zp, len, tx); - VERIFY(0 == dmu_buf_hold(zp->z_zfsvfs->z_os, + VERIFY(0 == dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)); dmu_buf_will_dirty(dbp, tx); @@ -122,13 +122,13 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx) void zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); xoptattr_t *xoap; ASSERT(MUTEX_HELD(&zp->z_lock)); VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); if (zp->z_is_sa) { - if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), + if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb), &xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp)) != 0) return; @@ -156,13 +156,13 @@ zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap) void zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); xoptattr_t *xoap; ASSERT(MUTEX_HELD(&zp->z_lock)); VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); if (zp->z_is_sa) - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb), &xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp), tx)); else { @@ -179,7 +179,7 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp)); zp->z_pflags |= ZFS_BONUS_SCANSTAMP; - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs), + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zsb), &zp->z_pflags, sizeof (uint64_t), tx)); } } @@ -198,7 +198,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) { dmu_buf_t *db = sa_get_db(hdl); znode_t *zp = sa_get_userdata(hdl); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); int count = 0; sa_bulk_attr_t *bulk, *sa_attrs; zfs_acl_locator_cb_t locate = { 0 }; @@ -216,7 +216,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) * and ready the ACL would require special "locked" * interfaces that would be messy */ - if (zp->z_acl_cached == NULL || ZTOV(zp)->v_type == VLNK) + if (zp->z_acl_cached == NULL || S_ISLNK(ZTOI(zp)->i_mode)) return; /* @@ -237,16 +237,16 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) /* First do a bulk query of the attributes that aren't cached */ bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zfsvfs), NULL, &rdev, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &uid, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &gid, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL, &znode_acl, 88); if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) { @@ -260,42 +260,42 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) */ count = 0; sa_attrs = kmem_zalloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zsb), NULL, &mode, 8); + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zsb), NULL, &uid, 8); + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zsb), NULL, &gid, 8); + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zsb), NULL, zp->z_atime, 16); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8); - if (zp->z_vnode->v_type == VBLK || zp->z_vnode->v_type == VCHR) - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zfsvfs), NULL, + if (S_ISBLK(ZTOI(zp)->i_mode) || S_ISCHR(ZTOI(zp)->i_mode)) + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zsb), NULL, &zp->z_acl_cached->z_acl_count, 8); if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID) zfs_acl_xform(zp, zp->z_acl_cached, CRED()); locate.cb_aclp = zp->z_acl_cached; - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zsb), zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes); if (xattr) - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8); #ifdef HAVE_SCANSTAMP @@ -304,7 +304,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) { bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, scanstamp, AV_SCANSTAMP_SZ); - SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zsb), NULL, scanstamp, AV_SCANSTAMP_SZ); zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP; } @@ -314,7 +314,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs, count, tx) == 0); if (znode_acl.z_acl_extern_obj) - VERIFY(0 == dmu_object_free(zfsvfs->z_os, + VERIFY(0 == dmu_object_free(zsb->z_os, znode_acl.z_acl_extern_obj, tx)); zp->z_is_sa = B_TRUE; @@ -328,7 +328,7 @@ done: void zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp) { - if (!zp->z_zfsvfs->z_use_sa || zp->z_is_sa) + if (!ZTOZSB(zp)->z_use_sa || zp->z_is_sa) return; diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 7c980b118..1763d171a 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -38,6 +38,7 @@ #include #include "fs/fs_subr.h" #include +#include #include #include #include @@ -62,13 +63,13 @@ #include #include #include +#include #include "zfs_comutil.h" -#ifdef HAVE_ZPL /*ARGSUSED*/ int -zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) +zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr) { /* * Data integrity is job one. We don't want a compromised kernel @@ -77,15 +78,14 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) if (unlikely(oops_in_progress)) return (0); - if (vfsp != NULL) { + if (zsb != NULL) { /* * Sync a specific filesystem. */ - zfsvfs_t *zfsvfs = vfsp->vfs_data; dsl_pool_t *dp; - ZFS_ENTER(zfsvfs); - dp = dmu_objset_pool(zfsvfs->z_os); + ZFS_ENTER(zsb); + dp = dmu_objset_pool(zsb->z_os); #ifdef HAVE_SHUTDOWN /* @@ -96,15 +96,15 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) * notifiers: {un}register_reboot_notifier(). */ if (sys_shutdown && spa_suspended(dp->dp_spa)) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } #endif /* HAVE_SHUTDOWN */ - if (zfsvfs->z_log != NULL) - zil_commit(zfsvfs->z_log, 0); + if (zsb->z_log != NULL) + zil_commit(zsb->z_log, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); } else { /* * Sync all ZFS filesystems. This is what happens when you @@ -121,113 +121,106 @@ EXPORT_SYMBOL(zfs_sync); static void atime_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + struct vfsmount *vfs = zsb->z_vfs; if (newval == TRUE) { - zfsvfs->z_atime = TRUE; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_ATIME, NULL, 0); + vfs->mnt_flags &= ~MNT_NOATIME; + sb->s_flags &= ~MS_NOATIME; + zsb->z_atime = TRUE; } else { - zfsvfs->z_atime = FALSE; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_ATIME); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME, NULL, 0); + vfs->mnt_flags |= MNT_NOATIME; + sb->s_flags |= MS_NOATIME; + zsb->z_atime = FALSE; } } static void xattr_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; if (newval == TRUE) { - /* XXX locking on vfs_flag? */ - zfsvfs->z_vfs->vfs_flag |= VFS_XATTR; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_XATTR, NULL, 0); + zsb->z_flags |= ZSB_XATTR_USER; } else { - /* XXX locking on vfs_flag? */ - zfsvfs->z_vfs->vfs_flag &= ~VFS_XATTR; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_XATTR); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR, NULL, 0); + zsb->z_flags &= ~ZSB_XATTR_USER; } } static void blksz_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; if (newval < SPA_MINBLOCKSIZE || newval > SPA_MAXBLOCKSIZE || !ISP2(newval)) newval = SPA_MAXBLOCKSIZE; - zfsvfs->z_max_blksz = newval; - zfsvfs->z_vfs->vfs_bsize = newval; + zsb->z_max_blksz = newval; } static void readonly_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + struct vfsmount *vfs = zsb->z_vfs; if (newval) { - /* XXX locking on vfs_flag? */ - zfsvfs->z_vfs->vfs_flag |= VFS_RDONLY; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RW); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RO, NULL, 0); + vfs->mnt_flags |= MNT_READONLY; + sb->s_flags |= MS_RDONLY; } else { - /* XXX locking on vfs_flag? */ - zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RO); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RW, NULL, 0); + vfs->mnt_flags &= ~MNT_READONLY; + sb->s_flags &= ~MS_RDONLY; } } static void devices_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + struct vfsmount *vfs = zsb->z_vfs; if (newval == FALSE) { - zfsvfs->z_vfs->vfs_flag |= VFS_NODEVICES; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_DEVICES); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NODEVICES, NULL, 0); + vfs->mnt_flags |= MNT_NODEV; + sb->s_flags |= MS_NODEV; } else { - zfsvfs->z_vfs->vfs_flag &= ~VFS_NODEVICES; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NODEVICES); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_DEVICES, NULL, 0); + vfs->mnt_flags &= ~MNT_NODEV; + sb->s_flags &= ~MS_NODEV; } } static void setuid_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + struct vfsmount *vfs = zsb->z_vfs; if (newval == FALSE) { - zfsvfs->z_vfs->vfs_flag |= VFS_NOSETUID; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_SETUID); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID, NULL, 0); + vfs->mnt_flags |= MNT_NOSUID; + sb->s_flags |= MS_NOSUID; } else { - zfsvfs->z_vfs->vfs_flag &= ~VFS_NOSETUID; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_SETUID, NULL, 0); + vfs->mnt_flags &= ~MNT_NOSUID; + sb->s_flags &= ~MS_NOSUID; } } static void exec_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + struct vfsmount *vfs = zsb->z_vfs; if (newval == FALSE) { - zfsvfs->z_vfs->vfs_flag |= VFS_NOEXEC; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_EXEC); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC, NULL, 0); + vfs->mnt_flags |= MNT_NOEXEC; + sb->s_flags |= MS_NOEXEC; } else { - zfsvfs->z_vfs->vfs_flag &= ~VFS_NOEXEC; - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_EXEC, NULL, 0); + vfs->mnt_flags &= ~MNT_NOEXEC; + sb->s_flags &= ~MS_NOEXEC; } } @@ -242,138 +235,89 @@ exec_changed_cb(void *arg, uint64_t newval) static void nbmand_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; - if (newval == FALSE) { - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NBMAND); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NONBMAND, NULL, 0); + zfs_sb_t *zsb = arg; + struct super_block *sb = zsb->z_sb; + + if (newval == TRUE) { + sb->s_flags |= MS_MANDLOCK; } else { - vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NONBMAND); - vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NBMAND, NULL, 0); + sb->s_flags &= ~MS_MANDLOCK; } } static void snapdir_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; - - zfsvfs->z_show_ctldir = newval; + ((zfs_sb_t *)arg)->z_show_ctldir = newval; } static void vscan_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; - - zfsvfs->z_vscan = newval; + ((zfs_sb_t *)arg)->z_vscan = newval; } static void acl_inherit_changed_cb(void *arg, uint64_t newval) { - zfsvfs_t *zfsvfs = arg; - - zfsvfs->z_acl_inherit = newval; + ((zfs_sb_t *)arg)->z_acl_inherit = newval; } int -zfs_register_callbacks(vfs_t *vfsp) +zfs_register_callbacks(zfs_sb_t *zsb) { + struct vfsmount *vfsp = zsb->z_vfs; struct dsl_dataset *ds = NULL; - objset_t *os = NULL; - zfsvfs_t *zfsvfs = NULL; + objset_t *os = zsb->z_os; uint64_t nbmand; - int readonly, do_readonly = B_FALSE; - int setuid, do_setuid = B_FALSE; - int exec, do_exec = B_FALSE; - int devices, do_devices = B_FALSE; - int xattr, do_xattr = B_FALSE; - int atime, do_atime = B_FALSE; + boolean_t readonly = B_FALSE; + boolean_t setuid = B_TRUE; + boolean_t exec = B_TRUE; + boolean_t devices = B_TRUE; + boolean_t xattr = B_TRUE; + boolean_t atime = B_TRUE; + char osname[MAXNAMELEN]; int error = 0; - ASSERT(vfsp); - zfsvfs = vfsp->vfs_data; - ASSERT(zfsvfs); - os = zfsvfs->z_os; - /* - * The act of registering our callbacks will destroy any mount - * options we may have. In order to enable temporary overrides - * of mount options, we stash away the current values and - * restore them after we register the callbacks. + * While Linux allows multiple vfs mounts per super block we have + * limited it artificially to one in zfs_fill_super. Thus it is + * safe for us to modify the vfs mount fails through the callbacks. */ - if (vfs_optionisset(vfsp, MNTOPT_RO, NULL) || - !spa_writeable(dmu_objset_spa(os))) { + if ((vfsp->mnt_flags & MNT_READONLY) || + !spa_writeable(dmu_objset_spa(os))) readonly = B_TRUE; - do_readonly = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_RW, NULL)) { - readonly = B_FALSE; - do_readonly = B_TRUE; - } - if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) { + + if (vfsp->mnt_flags & MNT_NOSUID) { devices = B_FALSE; setuid = B_FALSE; - do_devices = B_TRUE; - do_setuid = B_TRUE; } else { - if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) { + if (vfsp->mnt_flags & MNT_NODEV) devices = B_FALSE; - do_devices = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_DEVICES, NULL)) { - devices = B_TRUE; - do_devices = B_TRUE; - } + } - if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) { - setuid = B_FALSE; - do_setuid = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_SETUID, NULL)) { - setuid = B_TRUE; - do_setuid = B_TRUE; - } - } - if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL)) { + if (vfsp->mnt_flags & MNT_NOEXEC) exec = B_FALSE; - do_exec = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_EXEC, NULL)) { - exec = B_TRUE; - do_exec = B_TRUE; - } - if (vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL)) { - xattr = B_FALSE; - do_xattr = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL)) { - xattr = B_TRUE; - do_xattr = B_TRUE; - } - if (vfs_optionisset(vfsp, MNTOPT_NOATIME, NULL)) { + + if (vfsp->mnt_flags & MNT_NOATIME) atime = B_FALSE; - do_atime = B_TRUE; - } else if (vfs_optionisset(vfsp, MNTOPT_ATIME, NULL)) { - atime = B_TRUE; - do_atime = B_TRUE; - } /* - * nbmand is a special property. It can only be changed at - * mount time. + * nbmand is a special property which may only be changed at + * mount time. Unfortunately, Linux does not have a VFS mount + * flag instead this is a super block flag. So setting this + * option at mount time will have to wait until we can parse + * the mount option string. For now we rely on the nbmand + * value stored with the object set. Additional mount option + * string to be handled: * - * This is weird, but it is documented to only be changeable - * at mount time. + * case: sensitive|insensitive|mixed + * zerocopy: on|off */ - if (vfs_optionisset(vfsp, MNTOPT_NONBMAND, NULL)) { - nbmand = B_FALSE; - } else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) { - nbmand = B_TRUE; - } else { - char osname[MAXNAMELEN]; - dmu_objset_name(os, osname); - if ((error = dsl_prop_get_integer(osname, "nbmand", &nbmand, - NULL))) { - return (error); - } - } + dmu_objset_name(os, osname); + if ((error = dsl_prop_get_integer(osname, "nbmand", &nbmand, NULL))) + return (error); /* * Register property callbacks. @@ -383,45 +327,39 @@ zfs_register_callbacks(vfs_t *vfsp) * overboard... */ ds = dmu_objset_ds(os); - error = dsl_prop_register(ds, "atime", atime_changed_cb, zfsvfs); + error = dsl_prop_register(ds, + "atime", atime_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "xattr", xattr_changed_cb, zfsvfs); + "xattr", xattr_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "recordsize", blksz_changed_cb, zfsvfs); + "recordsize", blksz_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "readonly", readonly_changed_cb, zfsvfs); + "readonly", readonly_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "devices", devices_changed_cb, zfsvfs); + "devices", devices_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "setuid", setuid_changed_cb, zfsvfs); + "setuid", setuid_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "exec", exec_changed_cb, zfsvfs); + "exec", exec_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "snapdir", snapdir_changed_cb, zfsvfs); + "snapdir", snapdir_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "aclinherit", acl_inherit_changed_cb, zfsvfs); + "aclinherit", acl_inherit_changed_cb, zsb); error = error ? error : dsl_prop_register(ds, - "vscan", vscan_changed_cb, zfsvfs); + "vscan", vscan_changed_cb, zsb); if (error) goto unregister; /* - * Invoke our callbacks to restore temporary mount options. + * Invoke our callbacks to set required flags. */ - if (do_readonly) - readonly_changed_cb(zfsvfs, readonly); - if (do_setuid) - setuid_changed_cb(zfsvfs, setuid); - if (do_exec) - exec_changed_cb(zfsvfs, exec); - if (do_devices) - devices_changed_cb(zfsvfs, devices); - if (do_xattr) - xattr_changed_cb(zfsvfs, xattr); - if (do_atime) - atime_changed_cb(zfsvfs, atime); - - nbmand_changed_cb(zfsvfs, nbmand); + readonly_changed_cb(zsb, readonly); + setuid_changed_cb(zsb, setuid); + exec_changed_cb(zsb, exec); + devices_changed_cb(zsb, devices); + xattr_changed_cb(zsb, xattr); + atime_changed_cb(zsb, atime); + nbmand_changed_cb(zsb, nbmand); return (0); @@ -431,22 +369,21 @@ unregister: * registered, but this is OK; it will simply return ENOMSG, * which we will ignore. */ - (void) dsl_prop_unregister(ds, "atime", atime_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "xattr", xattr_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "readonly", readonly_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "devices", devices_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "setuid", setuid_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "exec", exec_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, zfsvfs); + (void) dsl_prop_unregister(ds, "atime", atime_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "xattr", xattr_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "readonly", readonly_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "devices", devices_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "setuid", setuid_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "exec", exec_changed_cb, zsb); + (void) dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, zsb); (void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb, - zfsvfs); - (void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zfsvfs); - return (error); + zsb); + (void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zsb); + return (error); } EXPORT_SYMBOL(zfs_register_callbacks); -#endif /* HAVE_ZPL */ static int zfs_space_delta_cb(dmu_object_type_t bonustype, void *data, @@ -497,9 +434,8 @@ zfs_space_delta_cb(dmu_object_type_t bonustype, void *data, return (error); } -#ifdef HAVE_ZPL static void -fuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr, +fuidstr_to_sid(zfs_sb_t *zsb, const char *fuidstr, char *domainbuf, int buflen, uid_t *ridp) { uint64_t fuid; @@ -507,7 +443,7 @@ fuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr, fuid = strtonum(fuidstr, NULL); - domain = zfs_fuid_find_by_idx(zfsvfs, FUID_INDEX(fuid)); + domain = zfs_fuid_find_by_idx(zsb, FUID_INDEX(fuid)); if (domain) (void) strlcpy(domainbuf, domain, buflen); else @@ -516,7 +452,7 @@ fuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr, } static uint64_t -zfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type) +zfs_userquota_prop_to_obj(zfs_sb_t *zsb, zfs_userquota_prop_t type) { switch (type) { case ZFS_PROP_USERUSED: @@ -524,9 +460,9 @@ zfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type) case ZFS_PROP_GROUPUSED: return (DMU_GROUPUSED_OBJECT); case ZFS_PROP_USERQUOTA: - return (zfsvfs->z_userquota_obj); + return (zsb->z_userquota_obj); case ZFS_PROP_GROUPQUOTA: - return (zfsvfs->z_groupquota_obj); + return (zsb->z_groupquota_obj); default: return (ENOTSUP); } @@ -534,7 +470,7 @@ zfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type) } int -zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +zfs_userspace_many(zfs_sb_t *zsb, zfs_userquota_prop_t type, uint64_t *cookiep, void *vbuf, uint64_t *bufsizep) { int error; @@ -543,23 +479,23 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, zfs_useracct_t *buf = vbuf; uint64_t obj; - if (!dmu_objset_userspace_present(zfsvfs->z_os)) + if (!dmu_objset_userspace_present(zsb->z_os)) return (ENOTSUP); - obj = zfs_userquota_prop_to_obj(zfsvfs, type); + obj = zfs_userquota_prop_to_obj(zsb, type); if (obj == 0) { *bufsizep = 0; return (0); } - for (zap_cursor_init_serialized(&zc, zfsvfs->z_os, obj, *cookiep); + for (zap_cursor_init_serialized(&zc, zsb->z_os, obj, *cookiep); (error = zap_cursor_retrieve(&zc, &za)) == 0; zap_cursor_advance(&zc)) { if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) > *bufsizep) break; - fuidstr_to_sid(zfsvfs, za.za_name, + fuidstr_to_sid(zsb, za.za_name, buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid); buf->zu_space = za.za_first_integer; @@ -580,14 +516,14 @@ EXPORT_SYMBOL(zfs_userspace_many); * buf must be big enough (eg, 32 bytes) */ static int -id_to_fuidstr(zfsvfs_t *zfsvfs, const char *domain, uid_t rid, +id_to_fuidstr(zfs_sb_t *zsb, const char *domain, uid_t rid, char *buf, boolean_t addok) { uint64_t fuid; int domainid = 0; if (domain && domain[0]) { - domainid = zfs_fuid_find_by_domain(zfsvfs, domain, NULL, addok); + domainid = zfs_fuid_find_by_domain(zsb, domain, NULL, addok); if (domainid == -1) return (ENOENT); } @@ -597,7 +533,7 @@ id_to_fuidstr(zfsvfs_t *zfsvfs, const char *domain, uid_t rid, } int -zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t *valp) { char buf[32]; @@ -606,18 +542,18 @@ zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, *valp = 0; - if (!dmu_objset_userspace_present(zfsvfs->z_os)) + if (!dmu_objset_userspace_present(zsb->z_os)) return (ENOTSUP); - obj = zfs_userquota_prop_to_obj(zfsvfs, type); + obj = zfs_userquota_prop_to_obj(zsb, type); if (obj == 0) return (0); - err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_FALSE); + err = id_to_fuidstr(zsb, domain, rid, buf, B_FALSE); if (err) return (err); - err = zap_lookup(zfsvfs->z_os, obj, buf, 8, 1, valp); + err = zap_lookup(zsb->z_os, obj, buf, 8, 1, valp); if (err == ENOENT) err = 0; return (err); @@ -625,7 +561,7 @@ zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, EXPORT_SYMBOL(zfs_userspace_one); int -zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, +zfs_set_userquota(zfs_sb_t *zsb, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t quota) { char buf[32]; @@ -637,74 +573,74 @@ zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, if (type != ZFS_PROP_USERQUOTA && type != ZFS_PROP_GROUPQUOTA) return (EINVAL); - if (zfsvfs->z_version < ZPL_VERSION_USERSPACE) + if (zsb->z_version < ZPL_VERSION_USERSPACE) return (ENOTSUP); - objp = (type == ZFS_PROP_USERQUOTA) ? &zfsvfs->z_userquota_obj : - &zfsvfs->z_groupquota_obj; + objp = (type == ZFS_PROP_USERQUOTA) ? &zsb->z_userquota_obj : + &zsb->z_groupquota_obj; - err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_TRUE); + err = id_to_fuidstr(zsb, domain, rid, buf, B_TRUE); if (err) return (err); - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_zap(tx, *objp ? *objp : DMU_NEW_OBJECT, B_TRUE, NULL); if (*objp == 0) { dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE, zfs_userquota_prop_prefixes[type]); } if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); err = dmu_tx_assign(tx, TXG_WAIT); if (err) { dmu_tx_abort(tx); return (err); } - mutex_enter(&zfsvfs->z_lock); + mutex_enter(&zsb->z_lock); if (*objp == 0) { - *objp = zap_create(zfsvfs->z_os, DMU_OT_USERGROUP_QUOTA, + *objp = zap_create(zsb->z_os, DMU_OT_USERGROUP_QUOTA, DMU_OT_NONE, 0, tx); - VERIFY(0 == zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, + VERIFY(0 == zap_add(zsb->z_os, MASTER_NODE_OBJ, zfs_userquota_prop_prefixes[type], 8, 1, objp, tx)); } - mutex_exit(&zfsvfs->z_lock); + mutex_exit(&zsb->z_lock); if (quota == 0) { - err = zap_remove(zfsvfs->z_os, *objp, buf, tx); + err = zap_remove(zsb->z_os, *objp, buf, tx); if (err == ENOENT) err = 0; } else { - err = zap_update(zfsvfs->z_os, *objp, buf, 8, 1, "a, tx); + err = zap_update(zsb->z_os, *objp, buf, 8, 1, "a, tx); } ASSERT(err == 0); if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); dmu_tx_commit(tx); return (err); } EXPORT_SYMBOL(zfs_set_userquota); boolean_t -zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid) +zfs_fuid_overquota(zfs_sb_t *zsb, boolean_t isgroup, uint64_t fuid) { char buf[32]; uint64_t used, quota, usedobj, quotaobj; int err; usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT; - quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj; + quotaobj = isgroup ? zsb->z_groupquota_obj : zsb->z_userquota_obj; - if (quotaobj == 0 || zfsvfs->z_replay) + if (quotaobj == 0 || zsb->z_replay) return (B_FALSE); (void) sprintf(buf, "%llx", (longlong_t)fuid); - err = zap_lookup(zfsvfs->z_os, quotaobj, buf, 8, 1, "a); + err = zap_lookup(zsb->z_os, quotaobj, buf, 8, 1, "a); if (err != 0) return (B_FALSE); - err = zap_lookup(zfsvfs->z_os, usedobj, buf, 8, 1, &used); + err = zap_lookup(zsb->z_os, usedobj, buf, 8, 1, &used); if (err != 0) return (B_FALSE); return (used >= quota); @@ -712,40 +648,40 @@ zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid) EXPORT_SYMBOL(zfs_fuid_overquota); boolean_t -zfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup) +zfs_owner_overquota(zfs_sb_t *zsb, znode_t *zp, boolean_t isgroup) { uint64_t fuid; uint64_t quotaobj; - quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj; + quotaobj = isgroup ? zsb->z_groupquota_obj : zsb->z_userquota_obj; fuid = isgroup ? zp->z_gid : zp->z_uid; - if (quotaobj == 0 || zfsvfs->z_replay) + if (quotaobj == 0 || zsb->z_replay) return (B_FALSE); - return (zfs_fuid_overquota(zfsvfs, isgroup, fuid)); + return (zfs_fuid_overquota(zsb, isgroup, fuid)); } EXPORT_SYMBOL(zfs_owner_overquota); int -zfsvfs_create(const char *osname, zfsvfs_t **zfvp) +zfs_sb_create(const char *osname, zfs_sb_t **zsbp) { objset_t *os; - zfsvfs_t *zfsvfs; + zfs_sb_t *zsb; uint64_t zval; int i, error; uint64_t sa_obj; - zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); + zsb = kmem_zalloc(sizeof (zfs_sb_t), KM_SLEEP); /* * We claim to always be readonly so we can open snapshots; * other ZPL code will prevent us from writing to snapshots. */ - error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os); + error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zsb, &os); if (error) { - kmem_free(zfsvfs, sizeof (zfsvfs_t)); + kmem_free(zsb, sizeof (zfs_sb_t)); return (error); } @@ -754,48 +690,48 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) * Should probably make this a kmem cache, shuffle fields, * and just bzero up to z_hold_mtx[]. */ - zfsvfs->z_vfs = NULL; - zfsvfs->z_parent = zfsvfs; - zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE; - zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; - zfsvfs->z_os = os; + zsb->z_vfs = NULL; + zsb->z_parent = zsb; + zsb->z_max_blksz = SPA_MAXBLOCKSIZE; + zsb->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; + zsb->z_os = os; - error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version); + error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version); if (error) { goto out; - } else if (zfsvfs->z_version > + } else if (zsb->z_version > zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) { (void) printk("Can't mount a version %lld file system " "on a version %lld pool\n. Pool must be upgraded to mount " - "this file system.", (u_longlong_t)zfsvfs->z_version, + "this file system.", (u_longlong_t)zsb->z_version, (u_longlong_t)spa_version(dmu_objset_spa(os))); error = ENOTSUP; goto out; } if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0) goto out; - zfsvfs->z_norm = (int)zval; + zsb->z_norm = (int)zval; if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0) goto out; - zfsvfs->z_utf8 = (zval != 0); + zsb->z_utf8 = (zval != 0); if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0) goto out; - zfsvfs->z_case = (uint_t)zval; + zsb->z_case = (uint_t)zval; /* * Fold case on file systems that are always or sometimes case * insensitive. */ - if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE || - zfsvfs->z_case == ZFS_CASE_MIXED) - zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER; + if (zsb->z_case == ZFS_CASE_INSENSITIVE || + zsb->z_case == ZFS_CASE_MIXED) + zsb->z_norm |= U8_TEXTPREP_TOUPPER; - zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); - zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); + zsb->z_use_fuids = USE_FUIDS(zsb->z_version, zsb->z_os); + zsb->z_use_sa = USE_SA(zsb->z_version, zsb->z_os); - if (zfsvfs->z_use_sa) { + if (zsb->z_use_sa) { /* should either have both of these objects or none */ error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); @@ -810,83 +746,83 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) } error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END, - &zfsvfs->z_attr_table); + &zsb->z_attr_table); if (error) goto out; - if (zfsvfs->z_version >= ZPL_VERSION_SA) + if (zsb->z_version >= ZPL_VERSION_SA) sa_register_update_callback(os, zfs_sa_upgrade); error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, - &zfsvfs->z_root); + &zsb->z_root); if (error) goto out; - ASSERT(zfsvfs->z_root != 0); + ASSERT(zsb->z_root != 0); error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1, - &zfsvfs->z_unlinkedobj); + &zsb->z_unlinkedobj); if (error) goto out; error = zap_lookup(os, MASTER_NODE_OBJ, zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA], - 8, 1, &zfsvfs->z_userquota_obj); + 8, 1, &zsb->z_userquota_obj); if (error && error != ENOENT) goto out; error = zap_lookup(os, MASTER_NODE_OBJ, zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA], - 8, 1, &zfsvfs->z_groupquota_obj); + 8, 1, &zsb->z_groupquota_obj); if (error && error != ENOENT) goto out; error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1, - &zfsvfs->z_fuid_obj); + &zsb->z_fuid_obj); if (error && error != ENOENT) goto out; error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1, - &zfsvfs->z_shares_dir); + &zsb->z_shares_dir); if (error && error != ENOENT) goto out; - mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL); - list_create(&zfsvfs->z_all_znodes, sizeof (znode_t), + mutex_init(&zsb->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&zsb->z_lock, NULL, MUTEX_DEFAULT, NULL); + list_create(&zsb->z_all_znodes, sizeof (znode_t), offsetof(znode_t, z_link_node)); - rrw_init(&zfsvfs->z_teardown_lock); - rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL); - rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL); + rrw_init(&zsb->z_teardown_lock); + rw_init(&zsb->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL); + rw_init(&zsb->z_fuid_lock, NULL, RW_DEFAULT, NULL); for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) - mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); + mutex_init(&zsb->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); - *zfvp = zfsvfs; + *zsbp = zsb; return (0); out: - dmu_objset_disown(os, zfsvfs); - *zfvp = NULL; - kmem_free(zfsvfs, sizeof (zfsvfs_t)); + dmu_objset_disown(os, zsb); + *zsbp = NULL; + kmem_free(zsb, sizeof (zfs_sb_t)); return (error); } static int -zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) +zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting) { int error; - error = zfs_register_callbacks(zfsvfs->z_vfs); + error = zfs_register_callbacks(zsb); if (error) return (error); /* - * Set the objset user_ptr to track its zfsvfs. + * Set the objset user_ptr to track its zsb. */ - mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); - dmu_objset_set_user(zfsvfs->z_os, zfsvfs); - mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); + mutex_enter(&zsb->z_os->os_user_ptr_lock); + dmu_objset_set_user(zsb->z_os, zsb); + mutex_exit(&zsb->z_os->os_user_ptr_lock); - zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data); + zsb->z_log = zil_open(zsb->z_os, zfs_get_data); /* * If we are not mounting (ie: online recv), then we don't @@ -900,11 +836,11 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) * During replay we remove the read only flag to * allow replays to succeed. */ - readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY; + readonly = zsb->z_vfs->mnt_flags & MNT_READONLY; if (readonly != 0) - zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY; + zsb->z_vfs->mnt_flags &= ~MNT_READONLY; else - zfs_unlinked_drain(zfsvfs); + zfs_unlinked_drain(zsb); /* * Parse and replay the intent log. @@ -933,157 +869,51 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) * allocated and in the unlinked set, and there is an * intent log record saying to allocate it. */ - if (spa_writeable(dmu_objset_spa(zfsvfs->z_os))) { + if (spa_writeable(dmu_objset_spa(zsb->z_os))) { if (zil_replay_disable) { - zil_destroy(zfsvfs->z_log, B_FALSE); + zil_destroy(zsb->z_log, B_FALSE); } else { - zfsvfs->z_replay = B_TRUE; - zil_replay(zfsvfs->z_os, zfsvfs, + zsb->z_replay = B_TRUE; + zil_replay(zsb->z_os, zsb, zfs_replay_vector); - zfsvfs->z_replay = B_FALSE; + zsb->z_replay = B_FALSE; } } - zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */ + zsb->z_vfs->mnt_flags |= readonly; /* restore readonly bit */ } return (0); } void -zfsvfs_free(zfsvfs_t *zfsvfs) +zfs_sb_free(zfs_sb_t *zsb) { int i; - extern krwlock_t zfsvfs_lock; /* in zfs_znode.c */ - /* - * This is a barrier to prevent the filesystem from going away in - * zfs_znode_move() until we can safely ensure that the filesystem is - * not unmounted. We consider the filesystem valid before the barrier - * and invalid after the barrier. - */ - rw_enter(&zfsvfs_lock, RW_READER); - rw_exit(&zfsvfs_lock); + zfs_fuid_destroy(zsb); - zfs_fuid_destroy(zfsvfs); - - mutex_destroy(&zfsvfs->z_znodes_lock); - mutex_destroy(&zfsvfs->z_lock); - list_destroy(&zfsvfs->z_all_znodes); - rrw_destroy(&zfsvfs->z_teardown_lock); - rw_destroy(&zfsvfs->z_teardown_inactive_lock); - rw_destroy(&zfsvfs->z_fuid_lock); + mutex_destroy(&zsb->z_znodes_lock); + mutex_destroy(&zsb->z_lock); + list_destroy(&zsb->z_all_znodes); + rrw_destroy(&zsb->z_teardown_lock); + rw_destroy(&zsb->z_teardown_inactive_lock); + rw_destroy(&zsb->z_fuid_lock); for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) - mutex_destroy(&zfsvfs->z_hold_mtx[i]); - kmem_free(zfsvfs, sizeof (zfsvfs_t)); + mutex_destroy(&zsb->z_hold_mtx[i]); + kmem_free(zsb, sizeof (zfs_sb_t)); } -#ifdef HAVE_FUID_FEATURES static void -zfs_set_fuid_feature(zfsvfs_t *zfsvfs) +zfs_set_fuid_feature(zfs_sb_t *zsb) { - zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); - if (zfsvfs->z_use_fuids && zfsvfs->z_vfs) { - vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE); - } - zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); + zsb->z_use_fuids = USE_FUIDS(zsb->z_version, zsb->z_os); + zsb->z_use_sa = USE_SA(zsb->z_version, zsb->z_os); } -#endif /* HAVE_FUID_FEATURES */ - -int -zfs_domount(vfs_t *vfsp, char *osname) -{ - uint64_t recordsize, fsid_guid; - int error = 0; - zfsvfs_t *zfsvfs; - - ASSERT(vfsp); - ASSERT(osname); - - error = zfsvfs_create(osname, &zfsvfs); - if (error) - return (error); - zfsvfs->z_vfs = vfsp; - - /* Initialize the generic filesystem structure. */ - vfsp->vfs_bcount = 0; - vfsp->vfs_data = NULL; - - if ((error = dsl_prop_get_integer(osname, "recordsize", - &recordsize, NULL))) - goto out; - - vfsp->vfs_bsize = recordsize; - vfsp->vfs_flag |= VFS_NOTRUNC; - vfsp->vfs_data = zfsvfs; - - /* - * The fsid is 64 bits, composed of an 8-bit fs type, which - * separates our fsid from any other filesystem types, and a - * 56-bit objset unique ID. The objset unique ID is unique to - * all objsets open on this system, provided by unique_create(). - * The 8-bit fs type must be put in the low bits of fsid[1] - * because that's where other Solaris filesystems put it. - */ - fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os); - ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0); - vfsp->vfs_fsid.val[0] = fsid_guid; - vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8); - -#ifdef HAVE_FUID_FEATURES - /* - * Set features for file system. - */ - zfs_set_fuid_feature(zfsvfs); - if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { - vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); - vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); - vfs_set_feature(vfsp, VFSFT_NOCASESENSITIVE); - } else if (zfsvfs->z_case == ZFS_CASE_MIXED) { - vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); - vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); - } - vfs_set_feature(vfsp, VFSFT_ZEROCOPY_SUPPORTED); -#endif /* HAVE_FUID_FEATURES */ - - if (dmu_objset_is_snapshot(zfsvfs->z_os)) { - uint64_t pval; - - atime_changed_cb(zfsvfs, B_FALSE); - readonly_changed_cb(zfsvfs, B_TRUE); - if ((error = dsl_prop_get_integer(osname,"xattr",&pval,NULL))) - goto out; - xattr_changed_cb(zfsvfs, pval); - zfsvfs->z_issnap = B_TRUE; - zfsvfs->z_os->os_sync = ZFS_SYNC_DISABLED; - - mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); - dmu_objset_set_user(zfsvfs->z_os, zfsvfs); - mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); - } else { - error = zfsvfs_setup(zfsvfs, B_TRUE); - } - - if (!zfsvfs->z_issnap) - zfsctl_create(zfsvfs); -out: - if (error) { - dmu_objset_disown(zfsvfs->z_os, zfsvfs); - zfsvfs_free(zfsvfs); - } - - return (error); -} -EXPORT_SYMBOL(zfs_domount); void -zfs_unregister_callbacks(zfsvfs_t *zfsvfs) +zfs_unregister_callbacks(zfs_sb_t *zsb) { - objset_t *os = zfsvfs->z_os; + objset_t *os = zsb->z_os; struct dsl_dataset *ds; /* @@ -1092,34 +922,34 @@ zfs_unregister_callbacks(zfsvfs_t *zfsvfs) if (!dmu_objset_is_snapshot(os)) { ds = dmu_objset_ds(os); VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "devices", devices_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, - zfsvfs) == 0); + zsb) == 0); VERIFY(dsl_prop_unregister(ds, "aclinherit", - acl_inherit_changed_cb, zfsvfs) == 0); + acl_inherit_changed_cb, zsb) == 0); VERIFY(dsl_prop_unregister(ds, "vscan", - vscan_changed_cb, zfsvfs) == 0); + vscan_changed_cb, zsb) == 0); } } EXPORT_SYMBOL(zfs_unregister_callbacks); @@ -1155,15 +985,15 @@ zfs_check_global_label(const char *dsname, const char *hexsl) #endif /* HAVE_MLSLABEL */ int -zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) +zfs_statvfs(struct dentry *dentry, struct kstatfs *statp) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; - dev32_t d32; + zfs_sb_t *zsb = dentry->d_sb->s_fs_info; uint64_t refdbytes, availbytes, usedobjs, availobjs; + uint32_t bshift; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); - dmu_objset_space(zfsvfs->z_os, + dmu_objset_space(zsb->z_os, &refdbytes, &availbytes, &usedobjs, &availobjs); /* @@ -1172,16 +1002,17 @@ zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) * and we report our blocksize as the filesystem's maximum blocksize. */ statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT; - statp->f_bsize = zfsvfs->z_max_blksz; + statp->f_bsize = zsb->z_max_blksz; + bshift = fls(statp->f_bsize) - 1; /* - * The following report "total" blocks of various kinds in the - * file system, but reported in terms of f_frsize - the - * "fragment" size. + * The following report "total" blocks of various kinds in + * the file system, but reported in terms of f_bsize - the + * "preferred" size. */ - statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT; - statp->f_bfree = availbytes >> SPA_MINBLOCKSHIFT; + statp->f_blocks = (refdbytes + availbytes) >> bshift; + statp->f_bfree = availbytes >> bshift; statp->f_bavail = statp->f_bfree; /* no root reservation */ /* @@ -1193,63 +1024,54 @@ zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) * and the number of blocks (each object will take at least a block). */ statp->f_ffree = MIN(availobjs, statp->f_bfree); - statp->f_favail = statp->f_ffree; /* no "root reservation" */ statp->f_files = statp->f_ffree + usedobjs; - - (void) cmpldev(&d32, vfsp->vfs_dev); - statp->f_fsid = d32; + statp->f_fsid.val[0] = 0; /* XXX: Map up some unique ID */ + statp->f_fsid.val[1] = 0; + statp->f_type = ZFS_SUPER_MAGIC; + statp->f_namelen = ZFS_MAXNAMELEN; /* - * We're a zfs filesystem. - */ - (void) strcpy(statp->f_basetype, MNTTYPE_ZFS); - - statp->f_flag = vf_to_stf(vfsp->vfs_flag); - - statp->f_namemax = ZFS_MAXNAMELEN; - - /* - * We have all of 32 characters to stuff a string here. + * We have all of 40 characters to stuff a string here. * Is there anything useful we could/should provide? */ - bzero(statp->f_fstr, sizeof (statp->f_fstr)); + bzero(statp->f_spare, sizeof (statp->f_spare)); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_statvfs); int -zfs_root(vfs_t *vfsp, vnode_t **vpp) +zfs_root(zfs_sb_t *zsb, struct inode **ipp) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; znode_t *rootzp; int error; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); - error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + error = zfs_zget(zsb, zsb->z_root, &rootzp); if (error == 0) - *vpp = ZTOV(rootzp); + *ipp = ZTOI(rootzp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_root); /* - * Teardown the zfsvfs::z_os. + * Teardown the zfs_sb_t::z_os. * * Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock' * and 'z_teardown_inactive_lock' held. */ -static int -zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) +int +zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting) { znode_t *zp; - rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG); + rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG); +#ifdef HAVE_DNLC if (!unmounting) { /* * We purge the parent filesystem's vfsp as the parent @@ -1257,28 +1079,29 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) * v_vfsp set to the parent's filesystem's vfsp. Note, * 'z_parent' is self referential for non-snapshots. */ - (void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0); + (void) dnlc_purge_vfsp(zsb->z_parent->z_vfs, 0); } +#endif /* HAVE_DNLC */ /* * Close the zil. NB: Can't close the zil while zfs_inactive * threads are blocked as zil_close can call zfs_inactive. */ - if (zfsvfs->z_log) { - zil_close(zfsvfs->z_log); - zfsvfs->z_log = NULL; + if (zsb->z_log) { + zil_close(zsb->z_log); + zsb->z_log = NULL; } - rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_WRITER); + rw_enter(&zsb->z_teardown_inactive_lock, RW_WRITER); /* * If we are not unmounting (ie: online recv) and someone already * unmounted this file system while we were doing the switcheroo, * or a reopen of z_os failed then just bail out now. */ - if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) { - rw_exit(&zfsvfs->z_teardown_inactive_lock); - rrw_exit(&zfsvfs->z_teardown_lock, FTAG); + if (!unmounting && (zsb->z_unmounted || zsb->z_os == NULL)) { + rw_exit(&zsb->z_teardown_inactive_lock); + rrw_exit(&zsb->z_teardown_lock, FTAG); return (EIO); } @@ -1289,14 +1112,14 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) * * Release all holds on dbufs. */ - mutex_enter(&zfsvfs->z_znodes_lock); - for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL; - zp = list_next(&zfsvfs->z_all_znodes, zp)) + mutex_enter(&zsb->z_znodes_lock); + for (zp = list_head(&zsb->z_all_znodes); zp != NULL; + zp = list_next(&zsb->z_all_znodes, zp)) if (zp->z_sa_hdl) { - ASSERT(ZTOV(zp)->v_count > 0); + ASSERT(atomic_read(&ZTOI(zp)->i_count) > 0); zfs_znode_dmu_fini(zp); } - mutex_exit(&zfsvfs->z_znodes_lock); + mutex_exit(&zsb->z_znodes_lock); /* * If we are unmounting, set the unmounted flag and let new vops @@ -1304,96 +1127,142 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) * other vops will fail with EIO. */ if (unmounting) { - zfsvfs->z_unmounted = B_TRUE; - rrw_exit(&zfsvfs->z_teardown_lock, FTAG); - rw_exit(&zfsvfs->z_teardown_inactive_lock); + zsb->z_unmounted = B_TRUE; + rrw_exit(&zsb->z_teardown_lock, FTAG); + rw_exit(&zsb->z_teardown_inactive_lock); } /* * z_os will be NULL if there was an error in attempting to reopen - * zfsvfs, so just return as the properties had already been + * zsb, so just return as the properties had already been + * * unregistered and cached data had been evicted before. */ - if (zfsvfs->z_os == NULL) + if (zsb->z_os == NULL) return (0); /* * Unregister properties. */ - zfs_unregister_callbacks(zfsvfs); + zfs_unregister_callbacks(zsb); /* * Evict cached data */ - if (dmu_objset_is_dirty_anywhere(zfsvfs->z_os)) - if (!(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY)) - txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0); - (void) dmu_objset_evict_dbufs(zfsvfs->z_os); + if (dmu_objset_is_dirty_anywhere(zsb->z_os)) + if (!(zsb->z_vfs->mnt_flags & MNT_READONLY)) + txg_wait_synced(dmu_objset_pool(zsb->z_os), 0); + (void) dmu_objset_evict_dbufs(zsb->z_os); return (0); } +int +zfs_domount(struct super_block *sb, void *data, int silent) +{ + zpl_mount_data_t *zmd = data; + const char *osname = zmd->z_osname; + zfs_sb_t *zsb; + struct inode *root_inode; + uint64_t recordsize; + int error; + + /* + * Linux allows multiple vfs mounts per super block. However, the + * zfs_sb_t only contains a pointer for a single vfs mount. This + * back reference in the long term could be extended to a list of + * vfs mounts if a hook were added to the kernel to notify us when + * a vfsmount is destroyed. Until then we must limit the number + * of mounts per super block to one. + */ + if (atomic_read(&sb->s_active) > 1) + return (EBUSY); + + error = zfs_sb_create(osname, &zsb); + if (error) + return (error); + + if ((error = dsl_prop_get_integer(osname, "recordsize", + &recordsize, NULL))) + goto out; + + zsb->z_sb = sb; + zsb->z_vfs = zmd->z_vfs; + sb->s_fs_info = zsb; + sb->s_magic = ZFS_SUPER_MAGIC; + sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_time_gran = 1; + sb->s_blocksize = recordsize; + sb->s_blocksize_bits = ilog2(recordsize); + + /* Set callback operations for the file system. */ + sb->s_op = &zpl_super_operations; + sb->s_xattr = zpl_xattr_handlers; +#ifdef HAVE_EXPORTS + sb->s_export_op = &zpl_export_operations; +#endif /* HAVE_EXPORTS */ + + /* Set features for file system. */ + zfs_set_fuid_feature(zsb); + + if (dmu_objset_is_snapshot(zsb->z_os)) { + uint64_t pval; + + atime_changed_cb(zsb, B_FALSE); + readonly_changed_cb(zsb, B_TRUE); + if ((error = dsl_prop_get_integer(osname,"xattr",&pval,NULL))) + goto out; + xattr_changed_cb(zsb, pval); + zsb->z_issnap = B_TRUE; + zsb->z_os->os_sync = ZFS_SYNC_DISABLED; + + mutex_enter(&zsb->z_os->os_user_ptr_lock); + dmu_objset_set_user(zsb->z_os, zsb); + mutex_exit(&zsb->z_os->os_user_ptr_lock); + } else { + error = zfs_sb_setup(zsb, B_TRUE); +#ifdef HAVE_SNAPSHOT + (void) zfs_snap_create(zsb); +#endif /* HAVE_SNAPSHOT */ + } + + /* Allocate a root inode for the filesystem. */ + error = zfs_root(zsb, &root_inode); + if (error) { + (void) zfs_umount(sb); + goto out; + } + + /* Allocate a root dentry for the filesystem */ + sb->s_root = d_alloc_root(root_inode); + if (sb->s_root == NULL) { + (void) zfs_umount(sb); + error = ENOMEM; + goto out; + } +out: + if (error) { + dmu_objset_disown(zsb->z_os, zsb); + zfs_sb_free(zsb); + } + + return (error); +} +EXPORT_SYMBOL(zfs_domount); + /*ARGSUSED*/ int -zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr) +zfs_umount(struct super_block *sb) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; + zfs_sb_t *zsb = sb->s_fs_info; objset_t *os; - int ret; - ret = secpolicy_fs_unmount(cr, vfsp); - if (ret) { - if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource), - ZFS_DELEG_PERM_MOUNT, cr)) - return (ret); - } - - /* - * We purge the parent filesystem's vfsp as the parent filesystem - * and all of its snapshots have their vnode's v_vfsp set to the - * parent's filesystem's vfsp. Note, 'z_parent' is self - * referential for non-snapshots. - */ - (void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0); - - /* - * Unmount any snapshots mounted under .zfs before unmounting the - * dataset itself. - */ - if (zfsvfs->z_ctldir != NULL && - (ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) { - return (ret); - } - - if (!(fflag & MS_FORCE)) { - /* - * Check the number of active vnodes in the file system. - * Our count is maintained in the vfs structure, but the - * number is off by 1 to indicate a hold on the vfs - * structure itself. - * - * The '.zfs' directory maintains a reference of its - * own, and any active references underneath are - * reflected in the vnode count. - */ - if (zfsvfs->z_ctldir == NULL) { - if (vfsp->vfs_count > 1) - return (EBUSY); - } else { - if (vfsp->vfs_count > 2 || - zfsvfs->z_ctldir->v_count > 1) - return (EBUSY); - } - } - - vfsp->vfs_flag |= VFS_UNMOUNTED; - - VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0); - os = zfsvfs->z_os; + VERIFY(zfsvfs_teardown(zsb, B_TRUE) == 0); + os = zsb->z_os; /* * z_os will be NULL if there was an error in - * attempting to reopen zfsvfs. + * attempting to reopen zsb. */ if (os != NULL) { /* @@ -1406,33 +1275,28 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr) /* * Finally release the objset */ - dmu_objset_disown(os, zfsvfs); + dmu_objset_disown(os, zsb); } - /* - * We can now safely destroy the '.zfs' directory node. - */ - if (zfsvfs->z_ctldir != NULL) - zfsctl_destroy(zfsvfs); - + zfs_sb_free(zsb); return (0); } EXPORT_SYMBOL(zfs_umount); int -zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) +zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; + zfs_sb_t *zsb = VTOZSB(vfsp); znode_t *zp; uint64_t object = 0; uint64_t fid_gen = 0; uint64_t gen_mask; uint64_t zp_gen; - int i, err; + int i, err; - *vpp = NULL; + *ipp = NULL; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); if (fidp->fid_len == LONG_FID_LEN) { zfid_long_t *zlfid = (zfid_long_t *)fidp; @@ -1445,12 +1309,14 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) for (i = 0; i < sizeof (zlfid->zf_setgen); i++) setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); - err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs); +#ifdef HAVE_SNAPSHOT + err = zfsctl_lookup_objset(vfsp, objsetid, &zsb); if (err) return (EINVAL); - ZFS_ENTER(zfsvfs); +#endif /* HAVE_SNAPSHOT */ + ZFS_ENTER(zsb); } if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) { @@ -1462,103 +1328,104 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) for (i = 0; i < sizeof (zfid->zf_gen); i++) fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i); } else { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } +#ifdef HAVE_SNAPSHOT /* A zero fid_gen means we are in the .zfs control directories */ if (fid_gen == 0 && (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) { - *vpp = zfsvfs->z_ctldir; - ASSERT(*vpp != NULL); + *ipp = zsb->z_ctldir; + ASSERT(*ipp != NULL); if (object == ZFSCTL_INO_SNAPDIR) { - VERIFY(zfsctl_root_lookup(*vpp, "snapshot", vpp, NULL, + VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp, NULL, 0, NULL, NULL, NULL, NULL, NULL) == 0); } else { - VN_HOLD(*vpp); + igrab(*ipp); } - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } +#endif /* HAVE_SNAPSHOT */ gen_mask = -1ULL >> (64 - 8 * i); dprintf("getting %llu [%u mask %llx]\n", object, fid_gen, gen_mask); - if ((err = zfs_zget(zfsvfs, object, &zp))) { - ZFS_EXIT(zfsvfs); + if ((err = zfs_zget(zsb, object, &zp))) { + ZFS_EXIT(zsb); return (err); } - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), &zp_gen, + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zsb), &zp_gen, sizeof (uint64_t)); zp_gen = zp_gen & gen_mask; if (zp_gen == 0) zp_gen = 1; if (zp->z_unlinked || zp_gen != fid_gen) { dprintf("znode gen (%u) != fid gen (%u)\n", zp_gen, fid_gen); - VN_RELE(ZTOV(zp)); - ZFS_EXIT(zfsvfs); + iput(ZTOI(zp)); + ZFS_EXIT(zsb); return (EINVAL); } - *vpp = ZTOV(zp); - if (*vpp) - zfs_inode_update(VTOZ(*vpp)); + *ipp = ZTOI(zp); + if (*ipp) + zfs_inode_update(ITOZ(*ipp)); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_vget); /* - * Block out VOPs and close zfsvfs_t::z_os + * Block out VOPs and close zfs_sb_t::z_os * * Note, if successful, then we return with the 'z_teardown_lock' and * 'z_teardown_inactive_lock' write held. */ int -zfs_suspend_fs(zfsvfs_t *zfsvfs) +zfs_suspend_fs(zfs_sb_t *zsb) { int error; - if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) + if ((error = zfsvfs_teardown(zsb, B_FALSE)) != 0) return (error); - dmu_objset_disown(zfsvfs->z_os, zfsvfs); + dmu_objset_disown(zsb->z_os, zsb); return (0); } EXPORT_SYMBOL(zfs_suspend_fs); /* - * Reopen zfsvfs_t::z_os and release VOPs. + * Reopen zfs_sb_t::z_os and release VOPs. */ int -zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) +zfs_resume_fs(zfs_sb_t *zsb, const char *osname) { int err, err2; - ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock)); - ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); + ASSERT(RRW_WRITE_HELD(&zsb->z_teardown_lock)); + ASSERT(RW_WRITE_HELD(&zsb->z_teardown_inactive_lock)); - err = dmu_objset_own(osname, DMU_OST_ZFS, B_FALSE, zfsvfs, - &zfsvfs->z_os); + err = dmu_objset_own(osname, DMU_OST_ZFS, B_FALSE, zsb, &zsb->z_os); if (err) { - zfsvfs->z_os = NULL; + zsb->z_os = NULL; } else { znode_t *zp; uint64_t sa_obj = 0; - err2 = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, + err2 = zap_lookup(zsb->z_os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); - if ((err || err2) && zfsvfs->z_version >= ZPL_VERSION_SA) + if ((err || err2) && zsb->z_version >= ZPL_VERSION_SA) goto bail; - if ((err = sa_setup(zfsvfs->z_os, sa_obj, - zfs_attr_table, ZPL_END, &zfsvfs->z_attr_table)) != 0) + if ((err = sa_setup(zsb->z_os, sa_obj, + zfs_attr_table, ZPL_END, &zsb->z_attr_table)) != 0) goto bail; - VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0); + VERIFY(zfs_sb_setup(zsb, B_FALSE) == 0); /* * Attempt to re-establish all the active znodes with @@ -1566,78 +1433,51 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) * any potential callers discover that via ZFS_ENTER_VERIFY_VP * when they try to use their znode. */ - mutex_enter(&zfsvfs->z_znodes_lock); - for (zp = list_head(&zfsvfs->z_all_znodes); zp; - zp = list_next(&zfsvfs->z_all_znodes, zp)) { + mutex_enter(&zsb->z_znodes_lock); + for (zp = list_head(&zsb->z_all_znodes); zp; + zp = list_next(&zsb->z_all_znodes, zp)) { (void) zfs_rezget(zp); } - mutex_exit(&zfsvfs->z_znodes_lock); + mutex_exit(&zsb->z_znodes_lock); } bail: /* release the VOPs */ - rw_exit(&zfsvfs->z_teardown_inactive_lock); - rrw_exit(&zfsvfs->z_teardown_lock, FTAG); + rw_exit(&zsb->z_teardown_inactive_lock); + rrw_exit(&zsb->z_teardown_lock, FTAG); if (err) { /* - * Since we couldn't reopen zfsvfs::z_os, force + * Since we couldn't reopen zfs_sb_t::z_os, force * unmount this file system. */ - if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) - (void) dounmount(zfsvfs->z_vfs, MS_FORCE, CRED()); + (void) zfs_umount(zsb->z_sb); } return (err); } EXPORT_SYMBOL(zfs_resume_fs); -static void -zfs_freevfs(vfs_t *vfsp) -{ - zfsvfs_t *zfsvfs = vfsp->vfs_data; - - zfsvfs_free(zfsvfs); -} -#endif /* HAVE_ZPL */ - -void -zfs_init(void) -{ - zfsctl_init(); - zfs_znode_init(); - - dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); -} - -void -zfs_fini(void) -{ - zfsctl_fini(); - zfs_znode_fini(); -} - -#ifdef HAVE_ZPL int -zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) +zfs_set_version(zfs_sb_t *zsb, uint64_t newvers) { int error; - objset_t *os = zfsvfs->z_os; + objset_t *os = zsb->z_os; dmu_tx_t *tx; if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION) return (EINVAL); - if (newvers < zfsvfs->z_version) + if (newvers < zsb->z_version) return (EINVAL); if (zfs_spa_version_map(newvers) > - spa_version(dmu_objset_spa(zfsvfs->z_os))) + spa_version(dmu_objset_spa(zsb->z_os))) return (ENOTSUP); tx = dmu_tx_create(os); dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_FALSE, ZPL_VERSION_STR); - if (newvers >= ZPL_VERSION_SA && !zfsvfs->z_use_sa) { + if (newvers >= ZPL_VERSION_SA && !zsb->z_use_sa) { dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE, ZFS_SA_ATTRS); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); @@ -1656,10 +1496,10 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) return (error); } - if (newvers >= ZPL_VERSION_SA && !zfsvfs->z_use_sa) { + if (newvers >= ZPL_VERSION_SA && !zsb->z_use_sa) { uint64_t sa_obj; - ASSERT3U(spa_version(dmu_objset_spa(zfsvfs->z_os)), >=, + ASSERT3U(spa_version(dmu_objset_spa(zsb->z_os)), >=, SPA_VERSION_SA); sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE, DMU_OT_NONE, 0, tx); @@ -1674,21 +1514,18 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) spa_history_log_internal(LOG_DS_UPGRADE, dmu_objset_spa(os), tx, "oldver=%llu newver=%llu dataset = %llu", - zfsvfs->z_version, newvers, dmu_objset_id(os)); + zsb->z_version, newvers, dmu_objset_id(os)); dmu_tx_commit(tx); - zfsvfs->z_version = newvers; + zsb->z_version = newvers; -#ifdef HAVE_FUID_FEATURES - if (zfsvfs->z_version >= ZPL_VERSION_FUID) - zfs_set_fuid_feature(zfsvfs); -#endif /* HAVE_FUID_FEATURES */ + if (zsb->z_version >= ZPL_VERSION_FUID) + zfs_set_fuid_feature(zsb); return (0); } EXPORT_SYMBOL(zfs_set_version); -#endif /* HAVE_ZPL */ /* * Read a property stored within the master node. @@ -1731,3 +1568,18 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) } return (error); } + +void +zfs_init(void) +{ + zfs_znode_init(); + dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); + register_filesystem(&zpl_fs_type); +} + +void +zfs_fini(void) +{ + unregister_filesystem(&zpl_fs_type); + zfs_znode_fini(); +} diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 764f53040..a8019ba5c 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -25,7 +25,6 @@ /* Portions Copyright 2007 Jeremy Teo */ /* Portions Copyright 2010 Robert Milkowski */ -#ifdef HAVE_ZPL #include #include @@ -35,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -43,13 +41,7 @@ #include #include #include -#include -#include #include -#include -#include -#include -#include #include #include #include @@ -93,12 +85,12 @@ * to freed memory. The example below illustrates the following Big Rules: * * (1) A check must be made in each zfs thread for a mounted file system. - * This is done avoiding races using ZFS_ENTER(zfsvfs). - * A ZFS_EXIT(zfsvfs) is needed before all returns. Any znodes + * This is done avoiding races using ZFS_ENTER(zsb). + * A ZFS_EXIT(zsb) is needed before all returns. Any znodes * must be checked with ZFS_VERIFY_ZP(zp). Both of these macros * can return EIO from the calling function. * - * (2) VN_RELE() should always be the last thing except for zil_commit() + * (2) iput() should always be the last thing except for zil_commit() * (if necessary) and ZFS_EXIT(). This is for 3 reasons: * First, if it's the last reference, the vnode/znode * can be freed, so the zp may point to freed memory. Second, the last @@ -106,7 +98,7 @@ * pushing cached pages (which acquires range locks) and syncing out * cached atime changes. Third, zfs_zinactive() may require a new tx, * which could deadlock the system if you were already holding one. - * If you must call VN_RELE() within a tx then use VN_RELE_ASYNC(). + * If you must call iput() within a tx then use iput_ASYNC(). * * (3) All range locks must be grabbed before calling dmu_tx_assign(), * as they can span dmu_tx_assign() calls. @@ -122,7 +114,7 @@ * Thread A calls dmu_tx_assign(TXG_WAIT) and blocks in txg_wait_open() * forever, because the previous txg can't quiesce until B's tx commits. * - * If dmu_tx_assign() returns ERESTART and zfsvfs->z_assign is TXG_NOWAIT, + * If dmu_tx_assign() returns ERESTART and zsb->z_assign is TXG_NOWAIT, * then drop all locks, call dmu_tx_wait(), and try again. * * (5) If the operation succeeded, generate the intent log entry for it @@ -139,9 +131,9 @@ * * In general, this is how things should be ordered in each vnode op: * - * ZFS_ENTER(zfsvfs); // exit if unmounted + * ZFS_ENTER(zsb); // exit if unmounted * top: - * zfs_dirent_lock(&dl, ...) // lock directory entry (may VN_HOLD()) + * zfs_dirent_lock(&dl, ...) // lock directory entry (may igrab()) * rw_enter(...); // grab any other locks you need * tx = dmu_tx_create(...); // get DMU tx * dmu_tx_hold_*(); // hold each object you might modify @@ -149,14 +141,14 @@ * if (error) { * rw_exit(...); // drop locks * zfs_dirent_unlock(dl); // unlock directory entry - * VN_RELE(...); // release held vnodes + * iput(...); // release held vnodes * if (error == ERESTART) { * dmu_tx_wait(tx); * dmu_tx_abort(tx); * goto top; * } * dmu_tx_abort(tx); // abort DMU tx - * ZFS_EXIT(zfsvfs); // finished in zfs + * ZFS_EXIT(zsb); // finished in zfs * return (error); // really out of space * } * error = do_real_work(); // do whatever this VOP does @@ -165,163 +157,13 @@ * dmu_tx_commit(tx); // commit DMU tx -- error or not * rw_exit(...); // drop locks * zfs_dirent_unlock(dl); // unlock directory entry - * VN_RELE(...); // release held vnodes + * iput(...); // release held vnodes * zil_commit(zilog, foid); // synchronous when necessary - * ZFS_EXIT(zfsvfs); // finished in zfs + * ZFS_EXIT(zsb); // finished in zfs * return (error); // done, report error */ -/* ARGSUSED */ -static int -zfs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) -{ - znode_t *zp = VTOZ(*vpp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); - - if ((flag & FWRITE) && (zp->z_pflags & ZFS_APPENDONLY) && - ((flag & FAPPEND) == 0)) { - ZFS_EXIT(zfsvfs); - return (EPERM); - } - - if (!zfs_has_ctldir(zp) && zp->z_zfsvfs->z_vscan && - ZTOV(zp)->v_type == VREG && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) { - if (fs_vscan(*vpp, cr, 0) != 0) { - ZFS_EXIT(zfsvfs); - return (EACCES); - } - } - - /* Keep a count of the synchronous opens in the znode */ - if (flag & (FSYNC | FDSYNC)) - atomic_inc_32(&zp->z_sync_cnt); - - ZFS_EXIT(zfsvfs); - return (0); -} - -/* ARGSUSED */ -static int -zfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr, - caller_context_t *ct) -{ - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - - /* - * Clean up any locks held by this process on the vp. - */ - cleanlocks(vp, ddi_get_pid(), 0); - cleanshares(vp, ddi_get_pid()); - - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); - - /* Decrement the synchronous opens in the znode */ - if ((flag & (FSYNC | FDSYNC)) && (count == 1)) - atomic_dec_32(&zp->z_sync_cnt); - - if (!zfs_has_ctldir(zp) && zp->z_zfsvfs->z_vscan && - ZTOV(zp)->v_type == VREG && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) - VERIFY(fs_vscan(vp, cr, 1) == 0); - - ZFS_EXIT(zfsvfs); - return (0); -} - -/* - * Lseek support for finding holes (cmd == _FIO_SEEK_HOLE) and - * data (cmd == _FIO_SEEK_DATA). "off" is an in/out parameter. - */ -static int -zfs_holey(vnode_t *vp, int cmd, offset_t *off) -{ - znode_t *zp = VTOZ(vp); - uint64_t noff = (uint64_t)*off; /* new offset */ - uint64_t file_sz; - int error; - boolean_t hole; - - file_sz = zp->z_size; - if (noff >= file_sz) { - return (ENXIO); - } - - if (cmd == _FIO_SEEK_HOLE) - hole = B_TRUE; - else - hole = B_FALSE; - - error = dmu_offset_next(zp->z_zfsvfs->z_os, zp->z_id, hole, &noff); - - /* end of file? */ - if ((error == ESRCH) || (noff > file_sz)) { - /* - * Handle the virtual hole at the end of file. - */ - if (hole) { - *off = file_sz; - return (0); - } - return (ENXIO); - } - - if (noff < *off) - return (error); - *off = noff; - return (error); -} - -/* ARGSUSED */ -static int -zfs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred, - int *rvalp, caller_context_t *ct) -{ - offset_t off; - int error; - zfsvfs_t *zfsvfs; - znode_t *zp; - - switch (com) { - case _FIOFFS: - return (zfs_sync(vp->v_vfsp, 0, cred)); - - /* - * The following two ioctls are used by bfu. Faking out, - * necessary to avoid bfu errors. - */ - case _FIOGDIO: - case _FIOSDIO: - return (0); - - case _FIO_SEEK_DATA: - case _FIO_SEEK_HOLE: - if (ddi_copyin((void *)data, &off, sizeof (off), flag)) - return (EFAULT); - - zp = VTOZ(vp); - zfsvfs = zp->z_zfsvfs; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); - - /* offset parameter is in/out */ - error = zfs_holey(vp, com, &off); - ZFS_EXIT(zfsvfs); - if (error) - return (error); - if (ddi_copyout(&off, (void *)data, sizeof (off), flag)) - return (EFAULT); - return (0); - } - return (ENOTTY); -} - -#if defined(_KERNEL) && defined(HAVE_UIO_RW) +#if defined(_KERNEL) && defined(HAVE_MMAP) /* * Utility functions to map and unmap a single physical page. These * are used to manage the mappable copies of ZFS file data, and therefore @@ -346,7 +188,6 @@ zfs_unmap_page(page_t *pp, caddr_t addr) ppmapout(addr); } } -#endif /* _KERNEL && HAVE_UIO_RW */ /* * When a file is memory mapped, we must keep the IO data synchronized @@ -356,7 +197,8 @@ zfs_unmap_page(page_t *pp, caddr_t addr) * the page and the dmu buffer. */ static void -update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid) +update_pages(struct inode *ip, int64_t start, int len, objset_t *os, + uint64_t oid) { int64_t off; @@ -365,7 +207,7 @@ update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid) page_t *pp; uint64_t nbytes = MIN(PAGESIZE - off, len); - if (pp = page_lookup(vp, start, SE_SHARED)) { + if (pp = page_lookup(ip, start, SE_SHARED)) { caddr_t va; va = zfs_map_page(pp, S_WRITE); @@ -390,10 +232,10 @@ update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid) * the file is memory mapped. */ static int -mappedread(vnode_t *vp, int nbytes, uio_t *uio) +mappedread(struct inode *ip, int nbytes, uio_t *uio) { - znode_t *zp = VTOZ(vp); - objset_t *os = zp->z_zfsvfs->z_os; + znode_t *zp = ITOZ(ip); + objset_t *os = ITOZSB(ip)->z_os; int64_t start, off; int len = nbytes; int error = 0; @@ -404,7 +246,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) page_t *pp; uint64_t bytes = MIN(PAGESIZE - off, len); - if (pp = page_lookup(vp, start, SE_SHARED)) { + if (pp = page_lookup(ip, start, SE_SHARED)) { caddr_t va; va = zfs_map_page(pp, S_READ); @@ -421,18 +263,18 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) } return (error); } +#endif /* _KERNEL && HAVE_MMAP */ offset_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */ /* * Read bytes from specified file into supplied buffer. * - * IN: vp - vnode of file to be read from. + * IN: ip - inode of file to be read from. * uio - structure supplying read location, range info, * and return buffer. * ioflag - SYNC flags; used to provide FRSYNC semantics. * cr - credentials of caller. - * ct - caller context * * OUT: uio - updated offset and range, buffer filled. * @@ -440,26 +282,28 @@ offset_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */ * error code if failure * * Side Effects: - * vp - atime updated if byte count > 0 + * inode - atime updated if byte count > 0 */ /* ARGSUSED */ int -zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) +zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); objset_t *os; ssize_t n, nbytes; int error = 0; rl_t *rl; +#ifdef HAVE_UIO_ZEROCOPY xuio_t *xuio = NULL; +#endif /* HAVE_UIO_ZEROCOPY */ - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - os = zfsvfs->z_os; + os = zsb->z_os; if (zp->z_pflags & ZFS_AV_QUARANTINED) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EACCES); } @@ -467,7 +311,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) * Validate file offset */ if (uio->uio_loffset < (offset_t)0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } @@ -475,26 +319,28 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) * Fasttrack empty reads */ if (uio->uio_resid == 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } +#ifdef HAVE_MANDLOCKS /* * Check for mandatory locks */ if (MANDMODE(zp->z_mode)) { - if (error = chklock(vp, FREAD, + if (error = chklock(ip, FREAD, uio->uio_loffset, uio->uio_resid, uio->uio_fmode, ct)) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } } +#endif /* HAVE_MANDLOCK */ /* * If we're in FRSYNC mode, sync out this znode before reading it. */ - if (ioflag & FRSYNC || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) - zil_commit(zfsvfs->z_log, zp->z_id); + if (ioflag & FRSYNC || zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zsb->z_log, zp->z_id); /* * Lock the range against changes. @@ -513,6 +359,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) ASSERT(uio->uio_loffset < zp->z_size); n = MIN(uio->uio_resid, zp->z_size - uio->uio_loffset); +#ifdef HAVE_UIO_ZEROCOPY if ((uio->uio_extflg == UIO_XUIO) && (((xuio_t *)uio)->xu_type == UIOTYPE_ZEROCOPY)) { int nblk; @@ -529,7 +376,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) } (void) dmu_xuio_init(xuio, nblk); - if (vn_has_cached_data(vp)) { + if (vn_has_cached_data(ip)) { /* * For simplicity, we always allocate a full buffer * even if we only expect to read a portion of a block. @@ -541,15 +388,21 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) } } } +#endif /* HAVE_UIO_ZEROCOPY */ while (n > 0) { nbytes = MIN(n, zfs_read_chunk_size - P2PHASE(uio->uio_loffset, zfs_read_chunk_size)); - if (vn_has_cached_data(vp)) - error = mappedread(vp, nbytes, uio); +/* XXX: Drop this, ARC update handled by zpl layer */ +#ifdef HAVE_MMAP + if (vn_has_cached_data(ip)) + error = mappedread(ip, nbytes, uio); else error = dmu_read_uio(os, zp->z_id, uio, nbytes); +#else + error = dmu_read_uio(os, zp->z_id, uio, nbytes); +#endif /* HAVE_MMAP */ if (error) { /* convert checksum errors into IO errors */ if (error == ECKSUM) @@ -562,9 +415,9 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) out: zfs_range_unlock(rl); - ZFS_ACCESSTIME_STAMP(zfsvfs, zp); + ZFS_ACCESSTIME_STAMP(zsb, zp); zfs_inode_update(zp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_read); @@ -572,12 +425,11 @@ EXPORT_SYMBOL(zfs_read); /* * Write the bytes to a file. * - * IN: vp - vnode of file to be written to. + * IN: ip - inode of file to be written to. * uio - structure supplying write location, range info, * and data buffer. * ioflag - FAPPEND flag set if in append mode. * cr - credentials of caller. - * ct - caller context (NFS/CIFS fem monitor only) * * OUT: uio - updated offset and range. * @@ -585,36 +437,36 @@ EXPORT_SYMBOL(zfs_read); * error code if failure * * Timestamps: - * vp - ctime|mtime updated if byte count > 0 + * ip - ctime|mtime updated if byte count > 0 */ /* ARGSUSED */ int -zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) +zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - rlim64_t limit = uio->uio_llimit; + znode_t *zp = ITOZ(ip); + rlim64_t limit = uio->uio_limit; ssize_t start_resid = uio->uio_resid; ssize_t tx_bytes; uint64_t end_size; dmu_tx_t *tx; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); zilog_t *zilog; offset_t woff; ssize_t n, nbytes; rl_t *rl; - int max_blksz = zfsvfs->z_max_blksz; - int error; + int max_blksz = zsb->z_max_blksz; + int error = 0; arc_buf_t *abuf; - iovec_t *aiov; + iovec_t *aiov = NULL; xuio_t *xuio = NULL; int i_iov = 0; - int iovcnt = uio->uio_iovcnt; iovec_t *iovp = uio->uio_iov; int write_eof; int count = 0; sa_bulk_attr_t bulk[4]; uint64_t mtime[2], ctime[2]; + ASSERTV(int iovcnt = uio->uio_iovcnt); /* * Fasttrack empty write @@ -626,14 +478,13 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T) limit = MAXOFFSET_T; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, - &zp->z_size, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8); /* @@ -642,31 +493,34 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || ((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) && (uio->uio_loffset < zp->z_size))) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EPERM); } - zilog = zfsvfs->z_log; + zilog = zsb->z_log; /* * Validate file offset */ woff = ioflag & FAPPEND ? zp->z_size : uio->uio_loffset; if (woff < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } +#ifdef HAVE_MANDLOCKS /* * Check for mandatory locks before calling zfs_range_lock() * in order to prevent a deadlock with locks set via fcntl(). */ if (MANDMODE((mode_t)zp->z_mode) && - (error = chklock(vp, FWRITE, woff, n, uio->uio_fmode, ct)) != 0) { - ZFS_EXIT(zfsvfs); + (error = chklock(ip, FWRITE, woff, n, uio->uio_fmode, ct)) != 0) { + ZFS_EXIT(zsb); return (error); } +#endif /* HAVE_MANDLOCKS */ +#ifdef HAVE_UIO_ZEROCOPY /* * Pre-fault the pages to ensure slow (eg NFS) pages * don't hold up txg. @@ -677,6 +531,7 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) xuio = (xuio_t *)uio; else uio_prefaultpages(MIN(n, max_blksz), uio); +#endif /* HAVE_UIO_ZEROCOPY */ /* * If in append mode, set the io offset pointer to eof. @@ -708,7 +563,7 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) if (woff >= limit) { zfs_range_unlock(rl); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EFBIG); } @@ -729,8 +584,8 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) abuf = NULL; woff = uio->uio_loffset; again: - if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) || - zfs_owner_overquota(zfsvfs, zp, B_TRUE)) { + if (zfs_owner_overquota(zsb, zp, B_FALSE) || + zfs_owner_overquota(zsb, zp, B_TRUE)) { if (abuf != NULL) dmu_return_arcbuf(abuf); error = EDQUOT; @@ -742,8 +597,6 @@ again: aiov = &iovp[i_iov]; abuf = dmu_xuio_arcbuf(xuio, i_iov); dmu_xuio_clear(xuio, i_iov); - DTRACE_PROBE3(zfs_cp_write, int, i_iov, - iovec_t *, aiov, arc_buf_t *, abuf); ASSERT((aiov->iov_base == abuf->b_data) || ((char *)aiov->iov_base - (char *)abuf->b_data + aiov->iov_len == arc_buf_size(abuf))); @@ -776,7 +629,7 @@ again: /* * Start a transaction. */ - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz)); zfs_sa_upgrade_txholds(tx, zp); @@ -835,7 +688,7 @@ again: if (tx_bytes < max_blksz && (!write_eof || aiov->iov_base != abuf->b_data)) { ASSERT(xuio); - dmu_write(zfsvfs->z_os, zp->z_id, woff, + dmu_write(zsb->z_os, zp->z_id, woff, aiov->iov_len, aiov->iov_base, tx); dmu_return_arcbuf(abuf); xuio_stat_wbuf_copied(); @@ -847,17 +700,20 @@ again: ASSERT(tx_bytes <= uio->uio_resid); uioskip(uio, tx_bytes); } - if (tx_bytes && vn_has_cached_data(vp)) { - update_pages(vp, woff, - tx_bytes, zfsvfs->z_os, zp->z_id); +/* XXX: Drop this, ARC update handled by zpl layer */ +#ifdef HAVE_MMAP + if (tx_bytes && vn_has_cached_data(ip)) { + update_pages(ip, woff, + tx_bytes, zsb->z_os, zp->z_id); } +#endif /* HAVE_MMAP */ /* * If we made no progress, we're done. If we made even * partial progress, update the znode and ZIL accordingly. */ if (tx_bytes == 0) { - (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zfsvfs), + (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb), (void *)&zp->z_size, sizeof (uint64_t), tx); dmu_tx_commit(tx); ASSERT(error != 0); @@ -884,7 +740,7 @@ again: uint64_t newmode; zp->z_mode &= ~(S_ISUID | S_ISGID); newmode = zp->z_mode; - (void) sa_update(zp->z_sa_hdl, SA_ZPL_MODE(zfsvfs), + (void) sa_update(zp->z_sa_hdl, SA_ZPL_MODE(zsb), (void *)&newmode, sizeof (uint64_t), tx); } mutex_exit(&zp->z_acl_lock); @@ -906,8 +762,8 @@ again: * the file size to the specified eof. Note, there's no * concurrency during replay. */ - if (zfsvfs->z_replay && zfsvfs->z_replay_eof != 0) - zp->z_size = zfsvfs->z_replay_eof; + if (zsb->z_replay && zsb->z_replay_eof != 0) + zp->z_size = zsb->z_replay_eof; error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); @@ -929,26 +785,36 @@ again: * If we're in replay mode, or we made no progress, return error. * Otherwise, it's at least a partial write, so it's successful. */ - if (zfsvfs->z_replay || uio->uio_resid == start_resid) { - ZFS_EXIT(zfsvfs); + if (zsb->z_replay || uio->uio_resid == start_resid) { + ZFS_EXIT(zsb); return (error); } if (ioflag & (FSYNC | FDSYNC) || - zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, zp->z_id); zfs_inode_update(zp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_write); +static void +iput_async(struct inode *ip, taskq_t *taskq) +{ + ASSERT(atomic_read(&ip->i_count) > 0); + if (atomic_read(&ip->i_count) == 1) + taskq_dispatch(taskq, (task_func_t *)iput, ip, TQ_SLEEP); + else + iput(ip); +} + void zfs_get_done(zgd_t *zgd, int error) { znode_t *zp = zgd->zgd_private; - objset_t *os = zp->z_zfsvfs->z_os; + objset_t *os = ZTOZSB(zp)->z_os; if (zgd->zgd_db) dmu_buf_rele(zgd->zgd_db, zgd); @@ -959,7 +825,7 @@ zfs_get_done(zgd_t *zgd, int error) * Release the vnode asynchronously as we currently have the * txg stopped from syncing. */ - VN_RELE_ASYNC(ZTOV(zp), dsl_pool_vnrele_taskq(dmu_objset_pool(os))); + iput_async(ZTOI(zp), dsl_pool_iput_taskq(dmu_objset_pool(os))); if (error == 0 && zgd->zgd_bp) zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); @@ -977,8 +843,8 @@ static int zil_fault_io = 0; int zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) { - zfsvfs_t *zfsvfs = arg; - objset_t *os = zfsvfs->z_os; + zfs_sb_t *zsb = arg; + objset_t *os = zsb->z_os; znode_t *zp; uint64_t object = lr->lr_foid; uint64_t offset = lr->lr_offset; @@ -994,20 +860,19 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) /* * Nothing to do if the file has been removed */ - if (zfs_zget(zfsvfs, object, &zp) != 0) + if (zfs_zget(zsb, object, &zp) != 0) return (ENOENT); if (zp->z_unlinked) { /* * Release the vnode asynchronously as we currently have the * txg stopped from syncing. */ - VN_RELE_ASYNC(ZTOV(zp), - dsl_pool_vnrele_taskq(dmu_objset_pool(os))); + iput_async(ZTOI(zp), dsl_pool_iput_taskq(dmu_objset_pool(os))); return (ENOENT); } zgd = (zgd_t *)kmem_zalloc(sizeof (zgd_t), KM_SLEEP); - zgd->zgd_zilog = zfsvfs->z_log; + zgd->zgd_zilog = zsb->z_log; zgd->zgd_private = zp; /* @@ -1092,15 +957,14 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) } /*ARGSUSED*/ -static int -zfs_access(vnode_t *vp, int mode, int flag, cred_t *cr, - caller_context_t *ct) +int +zfs_access(struct inode *ip, int mode, int flag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); int error; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); if (flag & V_ACE_MASK) @@ -1108,46 +972,23 @@ zfs_access(vnode_t *vp, int mode, int flag, cred_t *cr, else error = zfs_zaccess_rwx(zp, mode, flag, cr); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - -/* - * If vnode is for a device return a specfs vnode instead. - */ -static int -specvp_check(vnode_t **vpp, cred_t *cr) -{ - int error = 0; - - if (IS_DEVVP(*vpp)) { - struct vnode *svp; - - svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr); - VN_RELE(*vpp); - if (svp == NULL) - error = ENOSYS; - *vpp = svp; - } - return (error); -} - +EXPORT_SYMBOL(zfs_access); /* * Lookup an entry in a directory, or an extended attribute directory. - * If it exists, return a held vnode reference for it. + * If it exists, return a held inode reference for it. * - * IN: dvp - vnode of directory to search. + * IN: dip - inode of directory to search. * nm - name of entry to lookup. - * pnp - full pathname to lookup [UNUSED]. * flags - LOOKUP_XATTR set if looking for an attribute. - * rdir - root directory vnode [UNUSED]. * cr - credentials of caller. - * ct - caller context * direntflags - directory lookup flags * realpnp - returned pathname. * - * OUT: vpp - vnode of located entry, NULL if not found. + * OUT: ipp - inode of located entry, NULL if not found. * * RETURN: 0 if success * error code if failure @@ -1157,18 +998,17 @@ specvp_check(vnode_t **vpp, cred_t *cr) */ /* ARGSUSED */ int -zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, - int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, - int *direntflags, pathname_t *realpnp) +zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags, + cred_t *cr, int *direntflags, pathname_t *realpnp) { - znode_t *zdp = VTOZ(dvp); - zfsvfs_t *zfsvfs = zdp->z_zfsvfs; - int error = 0; + znode_t *zdp = ITOZ(dip); + zfs_sb_t *zsb = ITOZSB(dip); + int error = 0; /* fast path */ if (!(flags & (LOOKUP_XATTR | FIGNORECASE))) { - if (dvp->v_type != VDIR) { + if (!S_ISDIR(dip->i_mode)) { return (ENOTDIR); } else if (zdp->z_sa_hdl == NULL) { return (EIO); @@ -1177,44 +1017,44 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, if (nm[0] == 0 || (nm[0] == '.' && nm[1] == '\0')) { error = zfs_fastaccesschk_execute(zdp, cr); if (!error) { - *vpp = dvp; - VN_HOLD(*vpp); + *ipp = dip; + igrab(*ipp); return (0); } return (error); +#ifdef HAVE_DNLC } else { vnode_t *tvp = dnlc_lookup(dvp, nm); if (tvp) { error = zfs_fastaccesschk_execute(zdp, cr); if (error) { - VN_RELE(tvp); + iput(tvp); return (error); } if (tvp == DNLC_NO_VNODE) { - VN_RELE(tvp); + iput(tvp); return (ENOENT); } else { *vpp = tvp; return (specvp_check(vpp, cr)); } } +#endif /* HAVE_DNLC */ } } - DTRACE_PROBE2(zfs__fastpath__lookup__miss, vnode_t *, dvp, char *, nm); - - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zdp); - *vpp = NULL; + *ipp = NULL; if (flags & LOOKUP_XATTR) { /* * If the xattr property is off, refuse the lookup request. */ - if (!(zfsvfs->z_vfs->vfs_flag & VFS_XATTR)) { - ZFS_EXIT(zfsvfs); + if (!(zsb->z_flags & ZSB_XATTR_USER)) { + ZFS_EXIT(zsb); return (EINVAL); } @@ -1223,12 +1063,12 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, * Maybe someday we will. */ if (zdp->z_pflags & ZFS_XATTR) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } - if ((error = zfs_get_xattrdir(VTOZ(dvp), vpp, cr, flags))) { - ZFS_EXIT(zfsvfs); + if ((error = zfs_get_xattrdir(zdp, ipp, cr, flags))) { + ZFS_EXIT(zsb); return (error); } @@ -1236,18 +1076,18 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, * Do we have permission to get into attribute directory? */ - if ((error = zfs_zaccess(VTOZ(*vpp), ACE_EXECUTE, 0, + if ((error = zfs_zaccess(ITOZ(*ipp), ACE_EXECUTE, 0, B_FALSE, cr))) { - VN_RELE(*vpp); - *vpp = NULL; + iput(*ipp); + *ipp = NULL; } - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - if (dvp->v_type != VDIR) { - ZFS_EXIT(zfsvfs); + if (!S_ISDIR(dip->i_mode)) { + ZFS_EXIT(zsb); return (ENOTDIR); } @@ -1256,25 +1096,21 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, */ if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - if (zfsvfs->z_utf8 && u8_validate(nm, strlen(nm), + if (zsb->z_utf8 && u8_validate(nm, strlen(nm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } - error = zfs_dirlook(zdp, nm, vpp, flags, direntflags, realpnp); - if (error == 0) { - if (*vpp) - zfs_inode_update(VTOZ(*vpp)); + error = zfs_dirlook(zdp, nm, ipp, flags, direntflags, realpnp); + if ((error == 0) && (*ipp)) + zfs_inode_update(ITOZ(*ipp)); - error = specvp_check(vpp, cr); - } - - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_lookup); @@ -1282,42 +1118,39 @@ EXPORT_SYMBOL(zfs_lookup); /* * Attempt to create a new entry in a directory. If the entry * already exists, truncate the file if permissible, else return - * an error. Return the vp of the created or trunc'd file. + * an error. Return the ip of the created or trunc'd file. * - * IN: dvp - vnode of directory to put new file entry in. + * IN: dip - inode of directory to put new file entry in. * name - name of new file entry. * vap - attributes of new file. * excl - flag indicating exclusive or non-exclusive mode. * mode - mode to open file with. * cr - credentials of caller. * flag - large file flag [UNUSED]. - * ct - caller context - * vsecp - ACL to be set + * vsecp - ACL to be set * - * OUT: vpp - vnode of created or trunc'd entry. + * OUT: ipp - inode of created or trunc'd entry. * * RETURN: 0 if success * error code if failure * * Timestamps: - * dvp - ctime|mtime updated if new entry created - * vp - ctime|mtime always, atime if new + * dip - ctime|mtime updated if new entry created + * ip - ctime|mtime always, atime if new */ /* ARGSUSED */ int -zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, - int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct, - vsecattr_t *vsecp) +zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl, + int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp) { - znode_t *zp, *dzp = VTOZ(dvp); - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + znode_t *zp, *dzp = ITOZ(dip); + zfs_sb_t *zsb = ITOZSB(dip); zilog_t *zilog; objset_t *os; zfs_dirlock_t *dl; dmu_tx_t *tx; int error; - ksid_t *ksid; uid_t uid; gid_t gid; zfs_acl_ids_t acl_ids; @@ -1330,51 +1163,45 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, */ gid = crgetgid(cr); - ksid = crgetsid(cr, KSID_OWNER); - if (ksid) - uid = ksid_getid(ksid); - else - uid = crgetuid(cr); + uid = crgetuid(cr); - if (zfsvfs->z_use_fuids == B_FALSE && - (vsecp || (vap->va_mask & AT_XVATTR) || - IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) + if (zsb->z_use_fuids == B_FALSE && + (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) return (EINVAL); - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - os = zfsvfs->z_os; - zilog = zfsvfs->z_log; + os = zsb->z_os; + zilog = zsb->z_log; - if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), + if (zsb->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } +#ifdef HAVE_XVATTR if (vap->va_mask & AT_XVATTR) { if ((error = secpolicy_xvattr((xvattr_t *)vap, - crgetuid(cr), cr, vap->va_type)) != 0) { - ZFS_EXIT(zfsvfs); + crgetuid(cr), cr, vap->va_mode)) != 0) { + ZFS_EXIT(zsb); return (error); } } +#endif /* HAVE_XVATTR */ + top: - *vpp = NULL; - - if ((vap->va_mode & VSVTX) && secpolicy_vnode_stky_modify(cr)) - vap->va_mode &= ~VSVTX; - + *ipp = NULL; if (*name == '\0') { /* * Null component name refers to the directory itself. */ - VN_HOLD(dvp); + igrab(dip); zp = dzp; dl = NULL; error = 0; } else { - /* possible VN_HOLD(zp) */ + /* possible igrab(zp) */ int zflg = 0; if (flag & FIGNORECASE) @@ -1387,7 +1214,7 @@ top: zfs_acl_ids_free(&acl_ids); if (strcmp(name, "..") == 0) error = EISDIR; - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } } @@ -1410,8 +1237,7 @@ top: * extended attribute directories. */ - if ((dzp->z_pflags & ZFS_XATTR) && - (vap->va_type != VREG)) { + if ((dzp->z_pflags & ZFS_XATTR) && !S_ISREG(vap->va_mode)) { if (have_acl) zfs_acl_ids_free(&acl_ids); error = EINVAL; @@ -1423,7 +1249,7 @@ top: goto out; have_acl = B_TRUE; - if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { + if (zfs_acl_ids_overquota(zsb, &acl_ids)) { zfs_acl_ids_free(&acl_ids); error = EDQUOT; goto out; @@ -1434,12 +1260,12 @@ top: dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes + ZFS_SA_BASE_ATTR_SIZE); - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE); - if (!zfsvfs->z_use_sa && + if (!zsb->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, acl_ids.z_aclp->z_acl_bytes); @@ -1454,13 +1280,13 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); (void) zfs_link_create(dl, zp, tx, ZNEW); txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap); @@ -1483,14 +1309,14 @@ top: /* * Can't truncate an existing file if in exclusive mode. */ - if (excl == EXCL) { + if (excl) { error = EEXIST; goto out; } /* * Can't open a directory for writing. */ - if ((ZTOV(zp)->v_type == VDIR) && (mode & S_IWRITE)) { + if (S_ISDIR(ZTOI(zp)->i_mode)) { error = EISDIR; goto out; } @@ -1508,15 +1334,12 @@ top: /* * Truncate regular files if requested. */ - if ((ZTOV(zp)->v_type == VREG) && - (vap->va_mask & AT_SIZE) && (vap->va_size == 0)) { + if (S_ISREG(ZTOI(zp)->i_mode) && + (vap->va_mask & ATTR_SIZE) && (vap->va_size == 0)) { /* we can't hold any locks when calling zfs_freesp() */ zfs_dirent_unlock(dl); dl = NULL; error = zfs_freesp(zp, 0, 0, mode, TRUE); - if (error == 0) { - vnevent_create(ZTOV(zp), ct); - } } } out: @@ -1526,18 +1349,17 @@ out: if (error) { if (zp) - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); } else { zfs_inode_update(dzp); zfs_inode_update(zp); - *vpp = ZTOV(zp); - error = specvp_check(vpp, cr); + *ipp = ZTOI(zp); } - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_create); @@ -1545,54 +1367,54 @@ EXPORT_SYMBOL(zfs_create); /* * Remove an entry from a directory. * - * IN: dvp - vnode of directory to remove entry from. + * IN: dip - inode of directory to remove entry from. * name - name of entry to remove. * cr - credentials of caller. - * ct - caller context - * flags - case flags * * RETURN: 0 if success * error code if failure * * Timestamps: - * dvp - ctime|mtime - * vp - ctime (if nlink > 0) + * dip - ctime|mtime + * ip - ctime (if nlink > 0) */ uint64_t null_xattr = 0; /*ARGSUSED*/ int -zfs_remove(vnode_t *dvp, char *name, cred_t *cr, caller_context_t *ct, - int flags) +zfs_remove(struct inode *dip, char *name, cred_t *cr) { - znode_t *zp, *dzp = VTOZ(dvp); + znode_t *zp, *dzp = ITOZ(dip); znode_t *xzp; - vnode_t *vp; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + struct inode *ip; + zfs_sb_t *zsb = ITOZSB(dip); zilog_t *zilog; - uint64_t acl_obj, xattr_obj; - uint64_t xattr_obj_unlinked = 0; + uint64_t xattr_obj; + uint64_t xattr_obj_unlinked = 0; uint64_t obj = 0; zfs_dirlock_t *dl; dmu_tx_t *tx; - boolean_t may_delete_now, delete_now = FALSE; - boolean_t unlinked, toobig = FALSE; + boolean_t unlinked; uint64_t txtype; pathname_t *realnmp = NULL; +#ifdef HAVE_PN_UTILS pathname_t realnm; +#endif /* HAVE_PN_UTILS */ int error; int zflg = ZEXISTS; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; +#ifdef HAVE_PN_UTILS if (flags & FIGNORECASE) { zflg |= ZCILOOK; pn_alloc(&realnm); realnmp = &realnm; } +#endif /* HAVE_PN_UTILS */ top: xattr_obj = 0; @@ -1602,13 +1424,15 @@ top: */ if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, realnmp))) { +#ifdef HAVE_PN_UTILS if (realnmp) pn_free(realnmp); - ZFS_EXIT(zfsvfs); +#endif /* HAVE_PN_UTILS */ + ZFS_EXIT(zsb); return (error); } - vp = ZTOV(zp); + ip = ZTOI(zp); if ((error = zfs_zaccess_delete(dzp, zp, cr))) { goto out; @@ -1617,75 +1441,60 @@ top: /* * Need to use rmdir for removing directories. */ - if (vp->v_type == VDIR) { + if (S_ISDIR(ip->i_mode)) { error = EPERM; goto out; } - vnevent_remove(vp, dvp, name, ct); - +#ifdef HAVE_DNLC if (realnmp) dnlc_remove(dvp, realnmp->pn_buf); else dnlc_remove(dvp, name); - - mutex_enter(&vp->v_lock); - may_delete_now = ((vp->v_count == 1) && (!vn_has_cached_data(vp))); - mutex_exit(&vp->v_lock); +#endif /* HAVE_DNLC */ /* - * We may delete the znode now, or we may put it in the unlinked set; - * it depends on whether we're the last link, and on whether there are - * other holds on the vnode. So we dmu_tx_hold() the right things to - * allow for either case. + * We never delete the znode and always place it in the unlinked + * set. The dentry cache will always hold the last reference and + * is responsible for safely freeing the znode. */ obj = zp->z_id; - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_zap(tx, dzp->z_id, FALSE, name); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); zfs_sa_upgrade_txholds(tx, dzp); - if (may_delete_now) { - toobig = - zp->z_size > zp->z_blksz * DMU_MAX_DELETEBLKCNT; - /* if the file is too big, only hold_free a token amount */ - dmu_tx_hold_free(tx, zp->z_id, 0, - (toobig ? DMU_MAX_ACCESS : DMU_OBJECT_END)); - } /* are there any extended attributes? */ - error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), + error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xattr_obj, sizeof (xattr_obj)); if (error == 0 && xattr_obj) { - error = zfs_zget(zfsvfs, xattr_obj, &xzp); + error = zfs_zget(zsb, xattr_obj, &xzp); ASSERT3U(error, ==, 0); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE); } - mutex_enter(&zp->z_lock); - if ((acl_obj = zfs_external_acl(zp)) != 0 && may_delete_now) - dmu_tx_hold_free(tx, acl_obj, 0, DMU_OBJECT_END); - mutex_exit(&zp->z_lock); - /* charge as an update -- would be nice not to charge at all */ - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL); error = dmu_tx_assign(tx, TXG_NOWAIT); if (error) { zfs_dirent_unlock(dl); - VN_RELE(vp); + iput(ip); if (xzp) - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); if (error == ERESTART) { dmu_tx_wait(tx); dmu_tx_abort(tx); goto top; } +#ifdef HAVE_PN_UTILS if (realnmp) pn_free(realnmp); +#endif /* HAVE_PN_UTILS */ dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -1700,64 +1509,31 @@ top: } if (unlinked) { - /* * Hold z_lock so that we can make sure that the ACL obj * hasn't changed. Could have been deleted due to * zfs_sa_upgrade(). */ mutex_enter(&zp->z_lock); - mutex_enter(&vp->v_lock); - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xattr_obj_unlinked, sizeof (xattr_obj_unlinked)); - delete_now = may_delete_now && !toobig && - vp->v_count == 1 && !vn_has_cached_data(vp) && - xattr_obj == xattr_obj_unlinked && zfs_external_acl(zp) == - acl_obj; - mutex_exit(&vp->v_lock); - } - - if (delete_now) { - if (xattr_obj_unlinked) { - ASSERT3U(xzp->z_links, ==, 2); - mutex_enter(&xzp->z_lock); - xzp->z_unlinked = 1; - xzp->z_links = 0; - error = sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs), - &xzp->z_links, sizeof (xzp->z_links), tx); - ASSERT3U(error, ==, 0); - mutex_exit(&xzp->z_lock); - zfs_unlinked_add(xzp, tx); - - if (zp->z_is_sa) - error = sa_remove(zp->z_sa_hdl, - SA_ZPL_XATTR(zfsvfs), tx); - else - error = sa_update(zp->z_sa_hdl, - SA_ZPL_XATTR(zfsvfs), &null_xattr, - sizeof (uint64_t), tx); - ASSERT3U(error, ==, 0); - } - mutex_enter(&vp->v_lock); - vp->v_count--; - ASSERT3U(vp->v_count, ==, 0); - mutex_exit(&vp->v_lock); - mutex_exit(&zp->z_lock); - zfs_znode_delete(zp, tx); - } else if (unlinked) { mutex_exit(&zp->z_lock); zfs_unlinked_add(zp, tx); } txtype = TX_REMOVE; +#ifdef HAVE_PN_UTILS if (flags & FIGNORECASE) txtype |= TX_CI; +#endif /* HAVE_PN_UTILS */ zfs_log_remove(zilog, tx, txtype, dzp, name, obj); dmu_tx_commit(tx); out: +#ifdef HAVE_PN_UTILS if (realnmp) pn_free(realnmp); +#endif /* HAVE_PN_UTILS */ zfs_dirent_unlock(dl); zfs_inode_update(dzp); @@ -1765,103 +1541,97 @@ out: if (xzp) zfs_inode_update(xzp); - if (!delete_now) - VN_RELE(vp); + iput(ip); if (xzp) - VN_RELE(ZTOV(xzp)); + iput(ZTOI(xzp)); - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_remove); /* - * Create a new directory and insert it into dvp using the name + * Create a new directory and insert it into dip using the name * provided. Return a pointer to the inserted directory. * - * IN: dvp - vnode of directory to add subdir to. + * IN: dip - inode of directory to add subdir to. * dirname - name of new directory. * vap - attributes of new directory. * cr - credentials of caller. - * ct - caller context * vsecp - ACL to be set * - * OUT: vpp - vnode of created directory. + * OUT: ipp - inode of created directory. * * RETURN: 0 if success * error code if failure * * Timestamps: - * dvp - ctime|mtime updated - * vp - ctime|mtime|atime updated + * dip - ctime|mtime updated + * ipp - ctime|mtime|atime updated */ /*ARGSUSED*/ int -zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, - caller_context_t *ct, int flags, vsecattr_t *vsecp) +zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, struct inode **ipp, + cred_t *cr, int flags, vsecattr_t *vsecp) { - znode_t *zp, *dzp = VTOZ(dvp); - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + znode_t *zp, *dzp = ITOZ(dip); + zfs_sb_t *zsb = ITOZSB(dip); zilog_t *zilog; zfs_dirlock_t *dl; uint64_t txtype; dmu_tx_t *tx; int error; int zf = ZNEW; - ksid_t *ksid; uid_t uid; gid_t gid = crgetgid(cr); zfs_acl_ids_t acl_ids; boolean_t fuid_dirtied; - ASSERT(vap->va_type == VDIR); + ASSERT(S_ISDIR(vap->va_mode)); /* * If we have an ephemeral id, ACL, or XVATTR then * make sure file system is at proper version */ - ksid = crgetsid(cr, KSID_OWNER); - if (ksid) - uid = ksid_getid(ksid); - else - uid = crgetuid(cr); - if (zfsvfs->z_use_fuids == B_FALSE && - (vsecp || (vap->va_mask & AT_XVATTR) || - IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) + uid = crgetuid(cr); + if (zsb->z_use_fuids == B_FALSE && + (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) return (EINVAL); - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; if (dzp->z_pflags & ZFS_XATTR) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } - if (zfsvfs->z_utf8 && u8_validate(dirname, + if (zsb->z_utf8 && u8_validate(dirname, strlen(dirname), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } if (flags & FIGNORECASE) zf |= ZCILOOK; +#ifdef HAVE_XVATTR if (vap->va_mask & AT_XVATTR) { if ((error = secpolicy_xvattr((xvattr_t *)vap, - crgetuid(cr), cr, vap->va_type)) != 0) { - ZFS_EXIT(zfsvfs); + crgetuid(cr), cr, vap->va_mode)) != 0) { + ZFS_EXIT(zsb); return (error); } } +#endif /* HAVE_XVATTR */ if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, vsecp, &acl_ids)) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } /* @@ -1872,39 +1642,39 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, * to fail. */ top: - *vpp = NULL; + *ipp = NULL; if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, NULL, NULL))) { zfs_acl_ids_free(&acl_ids); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { + if (zfs_acl_ids_overquota(zsb, &acl_ids)) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EDQUOT); } /* * Add a new entry to the directory. */ - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); - if (!zfsvfs->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { + zfs_fuid_txhold(zsb, tx); + if (!zsb->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, acl_ids.z_aclp->z_acl_bytes); } @@ -1922,7 +1692,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -1932,14 +1702,14 @@ top: zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); /* * Now put new name in parent dir. */ (void) zfs_link_create(dl, zp, tx, ZNEW); - *vpp = ZTOV(zp); + *ipp = ZTOI(zp); txtype = zfs_log_create_txtype(Z_DIR, vsecp, vap); if (flags & FIGNORECASE) @@ -1953,12 +1723,12 @@ top: zfs_dirent_unlock(dl); - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); zfs_inode_update(dzp); zfs_inode_update(zp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_mkdir); @@ -1968,37 +1738,36 @@ EXPORT_SYMBOL(zfs_mkdir); * directory is the same as the subdir to be removed, the * remove will fail. * - * IN: dvp - vnode of directory to remove from. + * IN: dip - inode of directory to remove from. * name - name of directory to be removed. - * cwd - vnode of current working directory. + * cwd - inode of current working directory. * cr - credentials of caller. - * ct - caller context * flags - case flags * * RETURN: 0 if success * error code if failure * * Timestamps: - * dvp - ctime|mtime updated + * dip - ctime|mtime updated */ /*ARGSUSED*/ int -zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, - caller_context_t *ct, int flags) +zfs_rmdir(struct inode *dip, char *name, struct inode *cwd, cred_t *cr, + int flags) { - znode_t *dzp = VTOZ(dvp); + znode_t *dzp = ITOZ(dip); znode_t *zp; - vnode_t *vp; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + struct inode *ip; + zfs_sb_t *zsb = ITOZSB(dip); zilog_t *zilog; zfs_dirlock_t *dl; dmu_tx_t *tx; int error; int zflg = ZEXISTS; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; if (flags & FIGNORECASE) zflg |= ZCILOOK; @@ -2010,28 +1779,26 @@ top: */ if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL))) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - vp = ZTOV(zp); + ip = ZTOI(zp); if ((error = zfs_zaccess_delete(dzp, zp, cr))) { goto out; } - if (vp->v_type != VDIR) { + if (!S_ISDIR(ip->i_mode)) { error = ENOTDIR; goto out; } - if (vp == cwd) { + if (ip == cwd) { error = EINVAL; goto out; } - vnevent_rmdir(vp, dvp, name, ct); - /* * Grab a lock on the directory to make sure that noone is * trying to add (or lookup) entries while we are removing it. @@ -2044,10 +1811,10 @@ top: */ rw_enter(&zp->z_parent_lock, RW_WRITER); - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_zap(tx, dzp->z_id, FALSE, name); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL); zfs_sa_upgrade_txholds(tx, zp); zfs_sa_upgrade_txholds(tx, dzp); error = dmu_tx_assign(tx, TXG_NOWAIT); @@ -2055,14 +1822,14 @@ top: rw_exit(&zp->z_parent_lock); rw_exit(&zp->z_name_lock); zfs_dirent_unlock(dl); - VN_RELE(vp); + iput(ip); if (error == ERESTART) { dmu_tx_wait(tx); dmu_tx_abort(tx); goto top; } dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -2082,38 +1849,32 @@ top: out: zfs_dirent_unlock(dl); - VN_RELE(vp); + iput(ip); - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); zfs_inode_update(dzp); zfs_inode_update(zp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_rmdir); /* * Read as many directory entries as will fit into the provided - * buffer from the given directory cursor position (specified in - * the uio structure. + * dirent buffer from the given directory cursor position. * - * IN: vp - vnode of directory to read. - * uio - structure supplying read location, range info, - * and return buffer. - * cr - credentials of caller. - * ct - caller context - * flags - case flags + * IN: ip - inode of directory to read. + * dirent - buffer for directory entries. * - * OUT: uio - updated offset and range, buffer filled. - * eofp - set to true if end-of-file detected. + * OUT: dirent - filler buffer of directory entries. * * RETURN: 0 if success * error code if failure * * Timestamps: - * vp - atime updated + * ip - atime updated * * Note that the low 4 bits of the cookie returned by zap is always zero. * This allows us to use the low range for "special" directory entries: @@ -2121,70 +1882,42 @@ EXPORT_SYMBOL(zfs_rmdir); * we use the offset 2 for the '.zfs' directory. */ /* ARGSUSED */ -static int -zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, - caller_context_t *ct, int flags) +int +zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir, + loff_t *pos, cred_t *cr) { - znode_t *zp = VTOZ(vp); - iovec_t *iovp; - edirent_t *eodp; - dirent64_t *odp; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); objset_t *os; - caddr_t outbuf; - size_t bufsize; zap_cursor_t zc; zap_attribute_t zap; - uint_t bytes_wanted; - uint64_t offset; /* must be unsigned; checks for < 1 */ - uint64_t parent; - int local_eof; int outcount; int error; uint8_t prefetch; - boolean_t check_sysattrs; + int done = 0; + uint64_t parent; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), - &parent, sizeof (parent))) != 0) { - ZFS_EXIT(zfsvfs); - return (error); - } - - /* - * If we are not given an eof variable, - * use a local one. - */ - if (eofp == NULL) - eofp = &local_eof; - - /* - * Check for valid iov_len. - */ - if (uio->uio_iov->iov_len <= 0) { - ZFS_EXIT(zfsvfs); - return (EINVAL); - } + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zsb), + &parent, sizeof (parent))) != 0) + goto out; /* * Quit if directory has been removed (posix) */ - if ((*eofp = zp->z_unlinked) != 0) { - ZFS_EXIT(zfsvfs); - return (0); - } - error = 0; - os = zfsvfs->z_os; - offset = uio->uio_loffset; + if (zp->z_unlinked) + goto out; + + os = zsb->z_os; prefetch = zp->z_zn_prefetch; /* * Initialize the iterator cursor. */ - if (offset <= 3) { + if (*pos <= 3) { /* * Start iteration from the beginning of the directory. */ @@ -2193,55 +1926,28 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, /* * The offset is a serialized cursor. */ - zap_cursor_init_serialized(&zc, os, zp->z_id, offset); + zap_cursor_init_serialized(&zc, os, zp->z_id, *pos); } - /* - * Get space to change directory entries into fs independent format. - */ - iovp = uio->uio_iov; - bytes_wanted = iovp->iov_len; - if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) { - bufsize = bytes_wanted; - outbuf = kmem_alloc(bufsize, KM_SLEEP); - odp = (struct dirent64 *)outbuf; - } else { - bufsize = bytes_wanted; - odp = (struct dirent64 *)iovp->iov_base; - } - eodp = (struct edirent *)odp; - - /* - * If this VFS supports the system attribute view interface; and - * we're looking at an extended attribute directory; and we care - * about normalization conflicts on this vfs; then we must check - * for normalization conflicts with the sysattr name space. - */ - check_sysattrs = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && - (vp->v_flag & V_XATTRDIR) && zfsvfs->z_norm && - (flags & V_RDDIR_ENTFLAGS); - /* * Transform to file-system independent format */ outcount = 0; - while (outcount < bytes_wanted) { - ino64_t objnum; - ushort_t reclen; - off64_t *next = NULL; + while (!done) { + uint64_t objnum; /* * Special case `.', `..', and `.zfs'. */ - if (offset == 0) { + if (*pos == 0) { (void) strcpy(zap.za_name, "."); zap.za_normalization_conflict = 0; objnum = zp->z_id; - } else if (offset == 1) { + } else if (*pos == 1) { (void) strcpy(zap.za_name, ".."); zap.za_normalization_conflict = 0; objnum = parent; - } else if (offset == 2 && zfs_show_ctldir(zp)) { + } else if (*pos == 2 && zfs_show_ctldir(zp)) { (void) strcpy(zap.za_name, ZFS_CTLDIR_NAME); zap.za_normalization_conflict = 0; objnum = ZFSCTL_INO_ROOT; @@ -2249,8 +1955,8 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, /* * Grab next entry. */ - if (error = zap_cursor_retrieve(&zc, &zap)) { - if ((*eofp = (error == ENOENT)) != 0) + if ((error = zap_cursor_retrieve(&zc, &zap))) { + if (error == ENOENT) break; else goto update; @@ -2261,155 +1967,63 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, cmn_err(CE_WARN, "zap_readdir: bad directory " "entry, obj = %lld, offset = %lld\n", (u_longlong_t)zp->z_id, - (u_longlong_t)offset); + (u_longlong_t)*pos); error = ENXIO; goto update; } objnum = ZFS_DIRENT_OBJ(zap.za_first_integer); - /* - * MacOS X can extract the object type here such as: - * uint8_t type = ZFS_DIRENT_TYPE(zap.za_first_integer); - */ - - if (check_sysattrs && !zap.za_normalization_conflict) { - zap.za_normalization_conflict = - xattr_sysattr_casechk(zap.za_name); - } } - - if (flags & V_RDDIR_ACCFILTER) { - /* - * If we have no access at all, don't include - * this entry in the returned information - */ - znode_t *ezp; - if (zfs_zget(zp->z_zfsvfs, objnum, &ezp) != 0) - goto skip_entry; - if (!zfs_has_access(ezp, cr)) { - VN_RELE(ZTOV(ezp)); - goto skip_entry; - } - VN_RELE(ZTOV(ezp)); - } - - if (flags & V_RDDIR_ENTFLAGS) - reclen = EDIRENT_RECLEN(strlen(zap.za_name)); - else - reclen = DIRENT64_RECLEN(strlen(zap.za_name)); - - /* - * Will this entry fit in the buffer? - */ - if (outcount + reclen > bufsize) { - /* - * Did we manage to fit anything in the buffer? - */ - if (!outcount) { - error = EINVAL; - goto update; - } + done = filldir(dirent, zap.za_name, strlen(zap.za_name), + zap_cursor_serialize(&zc), objnum, 0); + if (done) { break; } - if (flags & V_RDDIR_ENTFLAGS) { - /* - * Add extended flag entry: - */ - eodp->ed_ino = objnum; - eodp->ed_reclen = reclen; - /* NOTE: ed_off is the offset for the *next* entry */ - next = &(eodp->ed_off); - eodp->ed_eflags = zap.za_normalization_conflict ? - ED_CASE_CONFLICT : 0; - (void) strncpy(eodp->ed_name, zap.za_name, - EDIRENT_NAMELEN(reclen)); - eodp = (edirent_t *)((intptr_t)eodp + reclen); - } else { - /* - * Add normal entry: - */ - odp->d_ino = objnum; - odp->d_reclen = reclen; - /* NOTE: d_off is the offset for the *next* entry */ - next = &(odp->d_off); - (void) strncpy(odp->d_name, zap.za_name, - DIRENT64_NAMELEN(reclen)); - odp = (dirent64_t *)((intptr_t)odp + reclen); - } - outcount += reclen; - - ASSERT(outcount <= bufsize); /* Prefetch znode */ - if (prefetch) + if (prefetch) { dmu_prefetch(os, objnum, 0, 0); - - skip_entry: - /* - * Move to the next entry, fill in the previous offset. - */ - if (offset > 2 || (offset == 2 && !zfs_show_ctldir(zp))) { - zap_cursor_advance(&zc); - offset = zap_cursor_serialize(&zc); - } else { - offset += 1; } - if (next) - *next = offset; + + if (*pos >= 2) { + zap_cursor_advance(&zc); + *pos = zap_cursor_serialize(&zc); + } else { + (*pos)++; + } } zp->z_zn_prefetch = B_FALSE; /* a lookup will re-enable pre-fetching */ - if (uio->uio_segflg == UIO_SYSSPACE && uio->uio_iovcnt == 1) { - iovp->iov_base += outcount; - iovp->iov_len -= outcount; - uio->uio_resid -= outcount; - } else if (error = uiomove(outbuf, (long)outcount, UIO_READ, uio)) { - /* - * Reset the pointer. - */ - offset = uio->uio_loffset; - } - update: zap_cursor_fini(&zc); - if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) - kmem_free(outbuf, bufsize); - if (error == ENOENT) error = 0; - ZFS_ACCESSTIME_STAMP(zfsvfs, zp); + ZFS_ACCESSTIME_STAMP(zsb, zp); + zfs_inode_update(zp); + +out: + ZFS_EXIT(zsb); - uio->uio_loffset = offset; - ZFS_EXIT(zfsvfs); return (error); } +EXPORT_SYMBOL(zfs_readdir); ulong_t zfs_fsync_sync_cnt = 4; int -zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) +zfs_fsync(struct inode *ip, int syncflag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - - /* - * Regardless of whether this is required for standards conformance, - * this is the logical behavior when fsync() is called on a file with - * dirty pages. We use B_ASYNC since the ZIL transactions are already - * going to be pushed out as part of the zil_commit(). - */ - if (vn_has_cached_data(vp) && !(syncflag & FNODSYNC) && - (vp->v_type == VREG) && !(IS_SWAPVP(vp))) - (void) VOP_PUTPAGE(vp, (offset_t)0, (size_t)0, B_ASYNC, cr, ct); + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); (void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt); - if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) { - ZFS_ENTER(zfsvfs); + if (zsb->z_os->os_sync != ZFS_SYNC_DISABLED) { + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - zil_commit(zfsvfs->z_log, zp->z_id); - ZFS_EXIT(zfsvfs); + zil_commit(zsb->z_log, zp->z_id); + ZFS_EXIT(zsb); } return (0); } @@ -2420,43 +2034,37 @@ EXPORT_SYMBOL(zfs_fsync); * Get the requested file attributes and place them in the provided * vattr structure. * - * IN: vp - vnode of file. - * vap - va_mask identifies requested attributes. - * If AT_XVATTR set, then optional attrs are requested + * IN: ip - inode of file. + * stat - kstat structure to fill in. * flags - ATTR_NOACLCHECK (CIFS server context) * cr - credentials of caller. - * ct - caller context * - * OUT: vap - attribute values. - * - * RETURN: 0 (always succeeds) + * OUT: stat - filled in kstat values. */ /* ARGSUSED */ int -zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct) +zfs_getattr(struct inode *ip, struct kstat *stat, int flags, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); int error = 0; uint64_t links; uint64_t mtime[2], ctime[2]; - xvattr_t *xvap = (xvattr_t *)vap; /* vap may be an xvattr_t * */ - xoptattr_t *xoap = NULL; + uint32_t blksz; boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; sa_bulk_attr_t bulk[2]; int count = 0; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - zfs_fuid_map_ids(zp, cr, &vap->va_uid, &vap->va_gid); + zfs_fuid_map_ids(zp, cr, &stat->uid, &stat->gid); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); if ((error = sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -2466,10 +2074,10 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, * always be allowed to read basic attributes of file. */ if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) && - (vap->va_uid != crgetuid(cr))) { + (stat->uid != crgetuid(cr))) { if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0, skipaclchk, cr))) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } } @@ -2480,142 +2088,36 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, */ mutex_enter(&zp->z_lock); - vap->va_type = vp->v_type; - vap->va_mode = zp->z_mode & MODEMASK; - vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev; - vap->va_nodeid = zp->z_id; - if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp)) + stat->ino = ip->i_ino; + stat->mode = zp->z_mode; + stat->uid = zp->z_uid; + stat->gid = zp->z_gid; + if ((zp->z_id == zsb->z_root) && zfs_show_ctldir(zp)) links = zp->z_links + 1; else links = zp->z_links; - vap->va_nlink = MIN(links, UINT32_MAX); /* nlink_t limit! */ - vap->va_size = zp->z_size; - vap->va_rdev = vp->v_rdev; - vap->va_seq = zp->z_seq; + stat->nlink = MIN(links, ZFS_LINK_MAX); + stat->size = i_size_read(ip); + stat->rdev = ip->i_rdev; + stat->dev = ip->i_rdev; - /* - * Add in any requested optional attributes and the create time. - * Also set the corresponding bits in the returned attribute bitmap. - */ - if ((xoap = xva_getxoptattr(xvap)) != NULL && zfsvfs->z_use_fuids) { - if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { - xoap->xoa_archive = - ((zp->z_pflags & ZFS_ARCHIVE) != 0); - XVA_SET_RTN(xvap, XAT_ARCHIVE); - } - - if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { - xoap->xoa_readonly = - ((zp->z_pflags & ZFS_READONLY) != 0); - XVA_SET_RTN(xvap, XAT_READONLY); - } - - if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { - xoap->xoa_system = - ((zp->z_pflags & ZFS_SYSTEM) != 0); - XVA_SET_RTN(xvap, XAT_SYSTEM); - } - - if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { - xoap->xoa_hidden = - ((zp->z_pflags & ZFS_HIDDEN) != 0); - XVA_SET_RTN(xvap, XAT_HIDDEN); - } - - if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { - xoap->xoa_nounlink = - ((zp->z_pflags & ZFS_NOUNLINK) != 0); - XVA_SET_RTN(xvap, XAT_NOUNLINK); - } - - if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) { - xoap->xoa_immutable = - ((zp->z_pflags & ZFS_IMMUTABLE) != 0); - XVA_SET_RTN(xvap, XAT_IMMUTABLE); - } - - if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) { - xoap->xoa_appendonly = - ((zp->z_pflags & ZFS_APPENDONLY) != 0); - XVA_SET_RTN(xvap, XAT_APPENDONLY); - } - - if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { - xoap->xoa_nodump = - ((zp->z_pflags & ZFS_NODUMP) != 0); - XVA_SET_RTN(xvap, XAT_NODUMP); - } - - if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) { - xoap->xoa_opaque = - ((zp->z_pflags & ZFS_OPAQUE) != 0); - XVA_SET_RTN(xvap, XAT_OPAQUE); - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { - xoap->xoa_av_quarantined = - ((zp->z_pflags & ZFS_AV_QUARANTINED) != 0); - XVA_SET_RTN(xvap, XAT_AV_QUARANTINED); - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) { - xoap->xoa_av_modified = - ((zp->z_pflags & ZFS_AV_MODIFIED) != 0); - XVA_SET_RTN(xvap, XAT_AV_MODIFIED); - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP) && - vp->v_type == VREG) { - zfs_sa_get_scanstamp(zp, xvap); - } - - if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { - uint64_t times[2]; - - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs), - times, sizeof (times)); - ZFS_TIME_DECODE(&xoap->xoa_createtime, times); - XVA_SET_RTN(xvap, XAT_CREATETIME); - } - - if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) { - xoap->xoa_reparse = ((zp->z_pflags & ZFS_REPARSE) != 0); - XVA_SET_RTN(xvap, XAT_REPARSE); - } - if (XVA_ISSET_REQ(xvap, XAT_GEN)) { - xoap->xoa_generation = zp->z_gen; - XVA_SET_RTN(xvap, XAT_GEN); - } - - if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) { - xoap->xoa_offline = - ((zp->z_pflags & ZFS_OFFLINE) != 0); - XVA_SET_RTN(xvap, XAT_OFFLINE); - } - - if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) { - xoap->xoa_sparse = - ((zp->z_pflags & ZFS_SPARSE) != 0); - XVA_SET_RTN(xvap, XAT_SPARSE); - } - } - - ZFS_TIME_DECODE(&vap->va_atime, zp->z_atime); - ZFS_TIME_DECODE(&vap->va_mtime, mtime); - ZFS_TIME_DECODE(&vap->va_ctime, ctime); + ZFS_TIME_DECODE(&stat->atime, zp->z_atime); + ZFS_TIME_DECODE(&stat->mtime, mtime); + ZFS_TIME_DECODE(&stat->ctime, ctime); mutex_exit(&zp->z_lock); - sa_object_size(zp->z_sa_hdl, &vap->va_blksize, &vap->va_nblocks); + sa_object_size(zp->z_sa_hdl, &blksz, &stat->blocks); + stat->blksize = (1 << ip->i_blkbits); if (zp->z_blksz == 0) { /* * Block size hasn't been set; suggest maximal I/O transfers. */ - vap->va_blksize = zfsvfs->z_max_blksz; + stat->blksize = zsb->z_max_blksz; } - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_getattr); @@ -2624,32 +2126,29 @@ EXPORT_SYMBOL(zfs_getattr); * Set the file attributes to the values contained in the * vattr structure. * - * IN: vp - vnode of file to be modified. + * IN: ip - inode of file to be modified. * vap - new attribute values. * If AT_XVATTR set, then optional attrs are being set * flags - ATTR_UTIME set if non-default time values provided. * - ATTR_NOACLCHECK (CIFS context only). * cr - credentials of caller. - * ct - caller context * * RETURN: 0 if success * error code if failure * * Timestamps: - * vp - ctime updated, mtime updated if size changed. + * ip - ctime updated, mtime updated if size changed. */ /* ARGSUSED */ int -zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, - caller_context_t *ct) +zfs_setattr(struct inode *ip, struct iattr *attr, int flags, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); zilog_t *zilog; dmu_tx_t *tx; vattr_t oldva; - xvattr_t tmpxvattr; - uint_t mask = vap->va_mask; + uint_t mask = attr->ia_valid; uint_t saved_mask; int trim_mask = 0; uint64_t new_mode; @@ -2660,10 +2159,8 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, int need_policy = FALSE; int err, err2; zfs_fuid_info_t *fuidp = NULL; - xvattr_t *xvap = (xvattr_t *)vap; /* vap may be an xvattr_t * */ - xoptattr_t *xoap; - zfs_acl_t *aclp; boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; + zfs_acl_t *aclp = NULL; boolean_t fuid_dirtied = B_FALSE; sa_bulk_attr_t bulk[7], xattr_bulk[7]; int count = 0, xattr_count = 0; @@ -2671,81 +2168,44 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, if (mask == 0) return (0); - if (mask & AT_NOSET) - return (EINVAL); - - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; /* * Make sure that if we have ephemeral uid/gid or xvattr specified * that file system is at proper version level */ - - if (zfsvfs->z_use_fuids == B_FALSE && - (((mask & AT_UID) && IS_EPHEMERAL(vap->va_uid)) || - ((mask & AT_GID) && IS_EPHEMERAL(vap->va_gid)) || - (mask & AT_XVATTR))) { - ZFS_EXIT(zfsvfs); + if (zsb->z_use_fuids == B_FALSE && + (((mask & ATTR_UID) && IS_EPHEMERAL(attr->ia_uid)) || + ((mask & ATTR_GID) && IS_EPHEMERAL(attr->ia_gid)))) { + ZFS_EXIT(zsb); return (EINVAL); } - if (mask & AT_SIZE && vp->v_type == VDIR) { - ZFS_EXIT(zfsvfs); + if (mask & ATTR_SIZE && S_ISDIR(ip->i_mode)) { + ZFS_EXIT(zsb); return (EISDIR); } - if (mask & AT_SIZE && vp->v_type != VREG && vp->v_type != VFIFO) { - ZFS_EXIT(zfsvfs); + if (mask & ATTR_SIZE && !S_ISREG(ip->i_mode) && !S_ISFIFO(ip->i_mode)) { + ZFS_EXIT(zsb); return (EINVAL); } - /* - * If this is an xvattr_t, then get a pointer to the structure of - * optional attributes. If this is NULL, then we have a vattr_t. - */ - xoap = xva_getxoptattr(xvap); - - xva_init(&tmpxvattr); - - /* - * Immutable files can only alter immutable bit and atime - */ - if ((zp->z_pflags & ZFS_IMMUTABLE) && - ((mask & (AT_SIZE|AT_UID|AT_GID|AT_MTIME|AT_MODE)) || - ((mask & AT_XVATTR) && XVA_ISSET_REQ(xvap, XAT_CREATETIME)))) { - ZFS_EXIT(zfsvfs); + if ((mask & ATTR_SIZE) && (zp->z_pflags & ZFS_READONLY)) { + ZFS_EXIT(zsb); return (EPERM); } - if ((mask & AT_SIZE) && (zp->z_pflags & ZFS_READONLY)) { - ZFS_EXIT(zfsvfs); - return (EPERM); - } - - /* - * Verify timestamps doesn't overflow 32 bits. - * ZFS can handle large timestamps, but 32bit syscalls can't - * handle times greater than 2039. This check should be removed - * once large timestamps are fully supported. - */ - if (mask & (AT_ATIME | AT_MTIME)) { - if (((mask & AT_ATIME) && TIMESPEC_OVERFLOW(&vap->va_atime)) || - ((mask & AT_MTIME) && TIMESPEC_OVERFLOW(&vap->va_mtime))) { - ZFS_EXIT(zfsvfs); - return (EOVERFLOW); - } - } - top: attrzp = NULL; aclp = NULL; /* Can this be moved to before the top label? */ - if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { - ZFS_EXIT(zfsvfs); + if (zsb->z_vfs->mnt_flags & MNT_READONLY) { + ZFS_EXIT(zsb); return (EROFS); } @@ -2753,10 +2213,10 @@ top: * First validate permissions */ - if (mask & AT_SIZE) { + if (mask & ATTR_SIZE) { err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr); if (err) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (err); } /* @@ -2766,27 +2226,22 @@ top: * should be addressed in openat(). */ /* XXX - would it be OK to generate a log record here? */ - err = zfs_freesp(zp, vap->va_size, 0, 0, FALSE); + err = zfs_freesp(zp, attr->ia_size, 0, 0, FALSE); if (err) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); + return (err); + } + + /* Careful negative Linux return code here */ + err = -vmtruncate(ip, attr->ia_size); + if (err) { + ZFS_EXIT(zsb); return (err); } } - if (mask & (AT_ATIME|AT_MTIME) || - ((mask & AT_XVATTR) && (XVA_ISSET_REQ(xvap, XAT_HIDDEN) || - XVA_ISSET_REQ(xvap, XAT_READONLY) || - XVA_ISSET_REQ(xvap, XAT_ARCHIVE) || - XVA_ISSET_REQ(xvap, XAT_OFFLINE) || - XVA_ISSET_REQ(xvap, XAT_SPARSE) || - XVA_ISSET_REQ(xvap, XAT_CREATETIME) || - XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) { - need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0, - skipaclchk, cr); - } - - if (mask & (AT_UID|AT_GID)) { - int idmask = (mask & (AT_UID|AT_GID)); + if (mask & (ATTR_UID|ATTR_GID)) { + int idmask = (mask & (ATTR_UID|ATTR_GID)); int take_owner; int take_group; @@ -2795,16 +2250,17 @@ top: * we may clear S_ISUID/S_ISGID bits. */ - if (!(mask & AT_MODE)) - vap->va_mode = zp->z_mode; + if (!(mask & ATTR_MODE)) + attr->ia_mode = zp->z_mode; /* * Take ownership or chgrp to group we are a member of */ - take_owner = (mask & AT_UID) && (vap->va_uid == crgetuid(cr)); - take_group = (mask & AT_GID) && - zfs_groupmember(zfsvfs, vap->va_gid, cr); + take_owner = (mask & ATTR_UID) && + (attr->ia_uid == crgetuid(cr)); + take_group = (mask & ATTR_GID) && + zfs_groupmember(zsb, attr->ia_gid, cr); /* * If both AT_UID and AT_GID are set then take_owner and @@ -2815,16 +2271,17 @@ top: * */ - if (((idmask == (AT_UID|AT_GID)) && take_owner && take_group) || - ((idmask == AT_UID) && take_owner) || - ((idmask == AT_GID) && take_group)) { + if (((idmask == (ATTR_UID|ATTR_GID)) && + take_owner && take_group) || + ((idmask == ATTR_UID) && take_owner) || + ((idmask == ATTR_GID) && take_group)) { if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0, skipaclchk, cr) == 0) { /* * Remove setuid/setgid for non-privileged users */ - secpolicy_setid_clear(vap, cr); - trim_mask = (mask & (AT_UID|AT_GID)); + secpolicy_setid_clear(attr, cr); + trim_mask = (mask & (ATTR_UID|ATTR_GID)); } else { need_policy = TRUE; } @@ -2836,100 +2293,18 @@ top: mutex_enter(&zp->z_lock); oldva.va_mode = zp->z_mode; zfs_fuid_map_ids(zp, cr, &oldva.va_uid, &oldva.va_gid); - if (mask & AT_XVATTR) { - /* - * Update xvattr mask to include only those attributes - * that are actually changing. - * - * the bits will be restored prior to actually setting - * the attributes so the caller thinks they were set. - */ - if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) { - if (xoap->xoa_appendonly != - ((zp->z_pflags & ZFS_APPENDONLY) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_APPENDONLY); - XVA_SET_REQ(&tmpxvattr, XAT_APPENDONLY); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { - if (xoap->xoa_nounlink != - ((zp->z_pflags & ZFS_NOUNLINK) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_NOUNLINK); - XVA_SET_REQ(&tmpxvattr, XAT_NOUNLINK); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) { - if (xoap->xoa_immutable != - ((zp->z_pflags & ZFS_IMMUTABLE) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_IMMUTABLE); - XVA_SET_REQ(&tmpxvattr, XAT_IMMUTABLE); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { - if (xoap->xoa_nodump != - ((zp->z_pflags & ZFS_NODUMP) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_NODUMP); - XVA_SET_REQ(&tmpxvattr, XAT_NODUMP); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) { - if (xoap->xoa_av_modified != - ((zp->z_pflags & ZFS_AV_MODIFIED) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_AV_MODIFIED); - XVA_SET_REQ(&tmpxvattr, XAT_AV_MODIFIED); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { - if ((vp->v_type != VREG && - xoap->xoa_av_quarantined) || - xoap->xoa_av_quarantined != - ((zp->z_pflags & ZFS_AV_QUARANTINED) != 0)) { - need_policy = TRUE; - } else { - XVA_CLR_REQ(xvap, XAT_AV_QUARANTINED); - XVA_SET_REQ(&tmpxvattr, XAT_AV_QUARANTINED); - } - } - - if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) { - mutex_exit(&zp->z_lock); - ZFS_EXIT(zfsvfs); - return (EPERM); - } - - if (need_policy == FALSE && - (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP) || - XVA_ISSET_REQ(xvap, XAT_OPAQUE))) { - need_policy = TRUE; - } - } mutex_exit(&zp->z_lock); - if (mask & AT_MODE) { + if (mask & ATTR_MODE) { if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) { - err = secpolicy_setid_setsticky_clear(vp, vap, + err = secpolicy_setid_setsticky_clear(ip, attr, &oldva, cr); if (err) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (err); } - trim_mask |= AT_MODE; + trim_mask |= ATTR_MODE; } else { need_policy = TRUE; } @@ -2945,65 +2320,65 @@ top: */ if (trim_mask) { - saved_mask = vap->va_mask; - vap->va_mask &= ~trim_mask; + saved_mask = attr->ia_valid; + attr->ia_valid &= ~trim_mask; } - err = secpolicy_vnode_setattr(cr, vp, vap, &oldva, flags, + err = secpolicy_vnode_setattr(cr, ip, attr, &oldva, flags, (int (*)(void *, int, cred_t *))zfs_zaccess_unix, zp); if (err) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (err); } if (trim_mask) - vap->va_mask |= saved_mask; + attr->ia_valid |= saved_mask; } /* * secpolicy_vnode_setattr, or take ownership may have * changed va_mask */ - mask = vap->va_mask; + mask = attr->ia_valid; - if ((mask & (AT_UID | AT_GID))) { - err = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), + if ((mask & (ATTR_UID | ATTR_GID))) { + err = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xattr_obj, sizeof (xattr_obj)); if (err == 0 && xattr_obj) { - err = zfs_zget(zp->z_zfsvfs, xattr_obj, &attrzp); + err = zfs_zget(ZTOZSB(zp), xattr_obj, &attrzp); if (err) goto out2; } - if (mask & AT_UID) { - new_uid = zfs_fuid_create(zfsvfs, - (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp); + if (mask & ATTR_UID) { + new_uid = zfs_fuid_create(zsb, + (uint64_t)attr->ia_uid, cr, ZFS_OWNER, &fuidp); if (new_uid != zp->z_uid && - zfs_fuid_overquota(zfsvfs, B_FALSE, new_uid)) { + zfs_fuid_overquota(zsb, B_FALSE, new_uid)) { if (attrzp) - VN_RELE(ZTOV(attrzp)); + iput(ZTOI(attrzp)); err = EDQUOT; goto out2; } } - if (mask & AT_GID) { - new_gid = zfs_fuid_create(zfsvfs, (uint64_t)vap->va_gid, + if (mask & ATTR_GID) { + new_gid = zfs_fuid_create(zsb, (uint64_t)attr->ia_gid, cr, ZFS_GROUP, &fuidp); if (new_gid != zp->z_gid && - zfs_fuid_overquota(zfsvfs, B_TRUE, new_gid)) { + zfs_fuid_overquota(zsb, B_TRUE, new_gid)) { if (attrzp) - VN_RELE(ZTOV(attrzp)); + iput(ZTOI(attrzp)); err = EDQUOT; goto out2; } } } - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); - if (mask & AT_MODE) { + if (mask & ATTR_MODE) { uint64_t pmode = zp->z_mode; uint64_t acl_obj; - new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT); + new_mode = (pmode & S_IFMT) | (attr->ia_mode & ~S_IFMT); zfs_acl_chmod_setattr(zp, &aclp, new_mode); @@ -3013,7 +2388,7 @@ top: * Are we upgrading ACL from old V0 format * to V1 format? */ - if (zfsvfs->z_version >= ZPL_VERSION_FUID && + if (zsb->z_version >= ZPL_VERSION_FUID && zfs_znode_acl_version(zp) == ZFS_ACL_VERSION_INITIAL) { dmu_tx_hold_free(tx, acl_obj, 0, @@ -3031,20 +2406,16 @@ top: mutex_exit(&zp->z_lock); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); } else { - if ((mask & AT_XVATTR) && - XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) - dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); - else - dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); + dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); } if (attrzp) { dmu_tx_hold_sa(tx, attrzp->z_sa_hdl, B_FALSE); } - fuid_dirtied = zfsvfs->z_fuid_dirty; + fuid_dirtied = zsb->z_fuid_dirty; if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); zfs_sa_upgrade_txholds(tx, zp); @@ -3065,49 +2436,49 @@ top: */ - if (mask & (AT_UID|AT_GID|AT_MODE)) + if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE)) mutex_enter(&zp->z_acl_lock); mutex_enter(&zp->z_lock); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, sizeof (zp->z_pflags)); if (attrzp) { - if (mask & (AT_UID|AT_GID|AT_MODE)) + if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE)) mutex_enter(&attrzp->z_acl_lock); mutex_enter(&attrzp->z_lock); SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, - SA_ZPL_FLAGS(zfsvfs), NULL, &attrzp->z_pflags, + SA_ZPL_FLAGS(zsb), NULL, &attrzp->z_pflags, sizeof (attrzp->z_pflags)); } - if (mask & (AT_UID|AT_GID)) { + if (mask & (ATTR_UID|ATTR_GID)) { - if (mask & AT_UID) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, + if (mask & ATTR_UID) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &new_uid, sizeof (new_uid)); zp->z_uid = new_uid; if (attrzp) { SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, - SA_ZPL_UID(zfsvfs), NULL, &new_uid, + SA_ZPL_UID(zsb), NULL, &new_uid, sizeof (new_uid)); attrzp->z_uid = new_uid; } } - if (mask & AT_GID) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), + if (mask & ATTR_GID) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &new_gid, sizeof (new_gid)); zp->z_gid = new_gid; if (attrzp) { SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, - SA_ZPL_GID(zfsvfs), NULL, &new_gid, + SA_ZPL_GID(zsb), NULL, &new_gid, sizeof (new_gid)); attrzp->z_gid = new_gid; } } - if (!(mask & AT_MODE)) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), + if (!(mask & ATTR_MODE)) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &new_mode, sizeof (new_mode)); new_mode = zp->z_mode; } @@ -3119,8 +2490,8 @@ top: } } - if (mask & AT_MODE) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, + if (mask & ATTR_MODE) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &new_mode, sizeof (new_mode)); zp->z_mode = new_mode; ASSERT3U((uintptr_t)aclp, !=, NULL); @@ -3133,34 +2504,34 @@ top: } - if (mask & AT_ATIME) { - ZFS_TIME_ENCODE(&vap->va_atime, zp->z_atime); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, + if (mask & ATTR_ATIME) { + ZFS_TIME_ENCODE(&attr->ia_atime, zp->z_atime); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL, &zp->z_atime, sizeof (zp->z_atime)); } - if (mask & AT_MTIME) { - ZFS_TIME_ENCODE(&vap->va_mtime, mtime); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, + if (mask & ATTR_MTIME) { + ZFS_TIME_ENCODE(&attr->ia_mtime, mtime); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, sizeof (mtime)); } /* XXX - shouldn't this be done *before* the ATIME/MTIME checks? */ - if (mask & AT_SIZE && !(mask & AT_MTIME)) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), + if (mask & ATTR_SIZE && !(mask & ATTR_MTIME)) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, sizeof (mtime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, sizeof (ctime)); zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); } else if (mask != 0) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, sizeof (ctime)); zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime, B_TRUE); if (attrzp) { SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, - SA_ZPL_CTIME(zfsvfs), NULL, + SA_ZPL_CTIME(zsb), NULL, &ctime, sizeof (ctime)); zfs_tstamp_update_setup(attrzp, STATE_CHANGED, mtime, ctime, B_TRUE); @@ -3171,50 +2542,18 @@ top: * update from toggling bit */ - if (xoap && (mask & AT_XVATTR)) { - - /* - * restore trimmed off masks - * so that return masks can be set for caller. - */ - - if (XVA_ISSET_REQ(&tmpxvattr, XAT_APPENDONLY)) { - XVA_SET_REQ(xvap, XAT_APPENDONLY); - } - if (XVA_ISSET_REQ(&tmpxvattr, XAT_NOUNLINK)) { - XVA_SET_REQ(xvap, XAT_NOUNLINK); - } - if (XVA_ISSET_REQ(&tmpxvattr, XAT_IMMUTABLE)) { - XVA_SET_REQ(xvap, XAT_IMMUTABLE); - } - if (XVA_ISSET_REQ(&tmpxvattr, XAT_NODUMP)) { - XVA_SET_REQ(xvap, XAT_NODUMP); - } - if (XVA_ISSET_REQ(&tmpxvattr, XAT_AV_MODIFIED)) { - XVA_SET_REQ(xvap, XAT_AV_MODIFIED); - } - if (XVA_ISSET_REQ(&tmpxvattr, XAT_AV_QUARANTINED)) { - XVA_SET_REQ(xvap, XAT_AV_QUARANTINED); - } - - if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) - ASSERT(vp->v_type == VREG); - - zfs_xvattr_set(zp, xvap, tx); - } - if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); if (mask != 0) - zfs_log_setattr(zilog, tx, TX_SETATTR, zp, vap, mask, fuidp); + zfs_log_setattr(zilog, tx, TX_SETATTR, zp, attr, mask, fuidp); mutex_exit(&zp->z_lock); - if (mask & (AT_UID|AT_GID|AT_MODE)) + if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE)) mutex_exit(&zp->z_acl_lock); if (attrzp) { - if (mask & (AT_UID|AT_GID|AT_MODE)) + if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE)) mutex_exit(&attrzp->z_acl_lock); mutex_exit(&attrzp->z_lock); } @@ -3226,7 +2565,7 @@ out: } if (attrzp) - VN_RELE(ZTOV(attrzp)); + iput(ZTOI(attrzp)); if (aclp) zfs_acl_free(aclp); @@ -3246,10 +2585,10 @@ out: } out2: - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (err); } EXPORT_SYMBOL(zfs_setattr); @@ -3270,7 +2609,7 @@ zfs_rename_unlock(zfs_zlock_t **zlpp) while ((zl = *zlpp) != NULL) { if (zl->zl_znode != NULL) - VN_RELE(ZTOV(zl->zl_znode)); + iput(ZTOI(zl->zl_znode)); rw_exit(zl->zl_rwlock); *zlpp = zl->zl_next; kmem_free(zl, sizeof (*zl)); @@ -3288,7 +2627,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) { zfs_zlock_t *zl; znode_t *zp = tdzp; - uint64_t rootid = zp->z_zfsvfs->z_root; + uint64_t rootid = ZTOZSB(zp)->z_root; uint64_t oidp = zp->z_id; krwlock_t *rwlp = &szp->z_parent_lock; krw_t rw = RW_WRITER; @@ -3336,12 +2675,12 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) return (0); if (rw == RW_READER) { /* i.e. not the first pass */ - int error = zfs_zget(zp->z_zfsvfs, oidp, &zp); + int error = zfs_zget(ZTOZSB(zp), oidp, &zp); if (error) return (error); zl->zl_znode = zp; } - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zp->z_zfsvfs), + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(ZTOZSB(zp)), &oidp, sizeof (oidp)); rwlp = &zp->z_parent_lock; rw = RW_READER; @@ -3355,30 +2694,28 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) * Move an entry from the provided source directory to the target * directory. Change the entry name as indicated. * - * IN: sdvp - Source directory containing the "old entry". + * IN: sdip - Source directory containing the "old entry". * snm - Old entry name. - * tdvp - Target directory to contain the "new entry". + * tdip - Target directory to contain the "new entry". * tnm - New entry name. * cr - credentials of caller. - * ct - caller context * flags - case flags * * RETURN: 0 if success * error code if failure * * Timestamps: - * sdvp,tdvp - ctime|mtime updated + * sdip,tdip - ctime|mtime updated */ /*ARGSUSED*/ int -zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr, - caller_context_t *ct, int flags) +zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm, + cred_t *cr, int flags) { znode_t *tdzp, *szp, *tzp; - znode_t *sdzp = VTOZ(sdvp); - zfsvfs_t *zfsvfs = sdzp->z_zfsvfs; + znode_t *sdzp = ITOZ(sdip); + zfs_sb_t *zsb = ITOZSB(sdip); zilog_t *zilog; - vnode_t *realvp; zfs_dirlock_t *sdl, *tdl; dmu_tx_t *tx; zfs_zlock_t *zl; @@ -3386,26 +2723,20 @@ zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr, int error = 0; int zflg = 0; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(sdzp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; - /* - * Make sure we have the real vp for the target directory. - */ - if (VOP_REALVP(tdvp, &realvp, ct) == 0) - tdvp = realvp; - - if (tdvp->v_vfsp != sdvp->v_vfsp || zfsctl_is_node(tdvp)) { - ZFS_EXIT(zfsvfs); + if (tdip->i_sb != sdip->i_sb) { + ZFS_EXIT(zsb); return (EXDEV); } - tdzp = VTOZ(tdvp); + tdzp = ITOZ(tdip); ZFS_VERIFY_ZP(tdzp); - if (zfsvfs->z_utf8 && u8_validate(tnm, + if (zsb->z_utf8 && u8_validate(tnm, strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } @@ -3423,7 +2754,7 @@ top: * See the comment in zfs_link() for why this is considered bad. */ if ((tdzp->z_pflags & ZFS_XATTR) != (sdzp->z_pflags & ZFS_XATTR)) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } @@ -3442,10 +2773,10 @@ top: * First compare the two name arguments without * considering any case folding. */ - int nofold = (zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER); + int nofold = (zsb->z_norm & ~U8_TEXTPREP_TOUPPER); cmp = u8_strcmp(snm, tnm, 0, nofold, U8_UNICODE_LATEST, &error); - ASSERT(error == 0 || !zfsvfs->z_utf8); + ASSERT(error == 0 || !zsb->z_utf8); if (cmp == 0) { /* * POSIX: "If the old argument and the new argument @@ -3453,7 +2784,7 @@ top: * the rename() function shall return successfully * and perform no other action." */ - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } /* @@ -3474,10 +2805,10 @@ top: * is an exact match, we will allow this to proceed as * a name-change request. */ - if ((zfsvfs->z_case == ZFS_CASE_INSENSITIVE || - (zfsvfs->z_case == ZFS_CASE_MIXED && + if ((zsb->z_case == ZFS_CASE_INSENSITIVE || + (zsb->z_case == ZFS_CASE_MIXED && flags & FIGNORECASE)) && - u8_strcmp(snm, tnm, 0, zfsvfs->z_norm, U8_UNICODE_LATEST, + u8_strcmp(snm, tnm, 0, zsb->z_norm, U8_UNICODE_LATEST, &error) == 0) { /* * case preserving rename request, require exact @@ -3517,7 +2848,7 @@ top: if (!terr) { zfs_dirent_unlock(tdl); if (tzp) - VN_RELE(ZTOV(tzp)); + iput(ZTOI(tzp)); } if (sdzp == tdzp) @@ -3525,19 +2856,19 @@ top: if (strcmp(snm, "..") == 0) serr = EINVAL; - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (serr); } if (terr) { zfs_dirent_unlock(sdl); - VN_RELE(ZTOV(szp)); + iput(ZTOI(szp)); if (sdzp == tdzp) rw_exit(&sdzp->z_name_lock); if (strcmp(tnm, "..") == 0) terr = EINVAL; - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (terr); } @@ -3551,7 +2882,7 @@ top: if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr))) goto out; - if (ZTOV(szp)->v_type == VDIR) { + if (S_ISDIR(ZTOI(szp)->i_mode)) { /* * Check to make sure rename is valid. * Can't do a move like this: /usr/a/b to /usr/a/b/c/d @@ -3567,13 +2898,13 @@ top: /* * Source and target must be the same type. */ - if (ZTOV(szp)->v_type == VDIR) { - if (ZTOV(tzp)->v_type != VDIR) { + if (S_ISDIR(ZTOI(szp)->i_mode)) { + if (!S_ISDIR(ZTOI(tzp)->i_mode)) { error = ENOTDIR; goto out; } } else { - if (ZTOV(tzp)->v_type == VDIR) { + if (S_ISDIR(ZTOI(tzp)->i_mode)) { error = EISDIR; goto out; } @@ -3589,19 +2920,7 @@ top: } } - vnevent_rename_src(ZTOV(szp), sdvp, snm, ct); - if (tzp) - vnevent_rename_dest(ZTOV(tzp), tdvp, tnm, ct); - - /* - * notify the target directory if it is not the same - * as source directory. - */ - if (tdvp != sdvp) { - vnevent_rename_dest_dir(tdvp, ct); - } - - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, sdzp->z_sa_hdl, B_FALSE); dmu_tx_hold_zap(tx, sdzp->z_id, FALSE, snm); @@ -3616,7 +2935,7 @@ top: } zfs_sa_upgrade_txholds(tx, szp); - dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); + dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL); error = dmu_tx_assign(tx, TXG_NOWAIT); if (error) { if (zl != NULL) @@ -3627,16 +2946,16 @@ top: if (sdzp == tdzp) rw_exit(&sdzp->z_name_lock); - VN_RELE(ZTOV(szp)); + iput(ZTOI(szp)); if (tzp) - VN_RELE(ZTOV(tzp)); + iput(ZTOI(tzp)); if (error == ERESTART) { dmu_tx_wait(tx); dmu_tx_abort(tx); goto top; } dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -3648,7 +2967,7 @@ top: if (error == 0) { szp->z_pflags |= ZFS_AV_MODIFIED; - error = sa_update(szp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs), + error = sa_update(szp->z_sa_hdl, SA_ZPL_FLAGS(zsb), (void *)&szp->z_pflags, sizeof (uint64_t), tx); ASSERT3U(error, ==, 0); @@ -3657,12 +2976,6 @@ top: zfs_log_rename(zilog, tx, TX_RENAME | (flags & FIGNORECASE ? TX_CI : 0), sdzp, sdl->dl_name, tdzp, tdl->dl_name, szp); - - /* - * Update path information for the target vnode - */ - vn_renamepath(tdvp, ZTOV(szp), tnm, - strlen(tnm)); } else { /* * At this point, we have successfully created @@ -3698,16 +3011,16 @@ out: zfs_inode_update(tdzp); zfs_inode_update(szp); - VN_RELE(ZTOV(szp)); + iput(ZTOI(szp)); if (tzp) { zfs_inode_update(tzp); - VN_RELE(ZTOV(tzp)); + iput(ZTOI(tzp)); } - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_rename); @@ -3715,29 +3028,29 @@ EXPORT_SYMBOL(zfs_rename); /* * Insert the indicated symbolic reference entry into the directory. * - * IN: dvp - Directory to contain new symbolic link. + * IN: dip - Directory to contain new symbolic link. * link - Name for new symlink entry. * vap - Attributes of new entry. * target - Target path of new symlink. + * * cr - credentials of caller. - * ct - caller context * flags - case flags * * RETURN: 0 if success * error code if failure * * Timestamps: - * dvp - ctime|mtime updated + * dip - ctime|mtime updated */ /*ARGSUSED*/ int -zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, cred_t *cr, - caller_context_t *ct, int flags) +zfs_symlink(struct inode *dip, char *name, vattr_t *vap, char *link, + struct inode **ipp, cred_t *cr, int flags) { - znode_t *zp, *dzp = VTOZ(dvp); + znode_t *zp, *dzp = ITOZ(dip); zfs_dirlock_t *dl; dmu_tx_t *tx; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ITOZSB(dip); zilog_t *zilog; uint64_t len = strlen(link); int error; @@ -3746,67 +3059,69 @@ zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, cred_t *cr, boolean_t fuid_dirtied; uint64_t txtype = TX_SYMLINK; - ASSERT(vap->va_type == VLNK); + ASSERT(S_ISLNK(vap->va_mode)); - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - zilog = zfsvfs->z_log; + zilog = zsb->z_log; - if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), + if (zsb->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } if (flags & FIGNORECASE) zflg |= ZCILOOK; if (len > MAXPATHLEN) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (ENAMETOOLONG); } if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, NULL, &acl_ids)) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } top: + *ipp = NULL; + /* * Attempt to lock directory; fail if entry already exists. */ error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL); if (error) { zfs_acl_ids_free(&acl_ids); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { + if (zfs_acl_ids_overquota(zsb, &acl_ids)) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EDQUOT); } - tx = dmu_tx_create(zfsvfs->z_os); - fuid_dirtied = zfsvfs->z_fuid_dirty; + tx = dmu_tx_create(zsb->z_os); + fuid_dirtied = zsb->z_fuid_dirty; dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len)); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes + ZFS_SA_BASE_ATTR_SIZE + len); dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE); - if (!zfsvfs->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { + if (!zsb->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, acl_ids.z_aclp->z_acl_bytes); } if (fuid_dirtied) - zfs_fuid_txhold(zfsvfs, tx); + zfs_fuid_txhold(zsb, tx); error = dmu_tx_assign(tx, TXG_NOWAIT); if (error) { zfs_dirent_unlock(dl); @@ -3817,7 +3132,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -3828,18 +3143,18 @@ top: zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); if (fuid_dirtied) - zfs_fuid_sync(zfsvfs, tx); + zfs_fuid_sync(zsb, tx); mutex_enter(&zp->z_lock); if (zp->z_is_sa) - error = sa_update(zp->z_sa_hdl, SA_ZPL_SYMLINK(zfsvfs), + error = sa_update(zp->z_sa_hdl, SA_ZPL_SYMLINK(zsb), link, len, tx); else zfs_sa_symlink(zp, link, len, tx); mutex_exit(&zp->z_lock); zp->z_size = len; - (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zfsvfs), + (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb), &zp->z_size, sizeof (zp->z_size), tx); /* * Insert the new object into the directory. @@ -3859,138 +3174,148 @@ top: zfs_dirent_unlock(dl); - VN_RELE(ZTOV(zp)); + *ipp = ZTOI(zp); + iput(ZTOI(zp)); - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_symlink); /* * Return, in the buffer contained in the provided uio structure, - * the symbolic path referred to by vp. + * the symbolic path referred to by ip. * - * IN: vp - vnode of symbolic link. - * uoip - structure to contain the link path. - * cr - credentials of caller. - * ct - caller context - * - * OUT: uio - structure to contain the link path. + * IN: dentry - dentry of symbolic link. + * nd - namedata for symlink * * RETURN: 0 if success * error code if failure * * Timestamps: - * vp - atime updated + * ip - atime updated */ /* ARGSUSED */ int -zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct) +zfs_follow_link(struct dentry *dentry, struct nameidata *nd) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + struct inode *ip = dentry->d_inode; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); + struct iovec iov; + uio_t uio; int error; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); + iov.iov_len = MAXPATHLEN + 1; + iov.iov_base = kmem_zalloc(iov.iov_len, KM_SLEEP); + + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = iov.iov_len; + uio.uio_segflg = UIO_SYSSPACE; + mutex_enter(&zp->z_lock); if (zp->z_is_sa) - error = sa_lookup_uio(zp->z_sa_hdl, - SA_ZPL_SYMLINK(zfsvfs), uio); + error = sa_lookup_uio(zp->z_sa_hdl, SA_ZPL_SYMLINK(zsb), &uio); else - error = zfs_sa_readlink(zp, uio); + error = zfs_sa_readlink(zp, &uio); mutex_exit(&zp->z_lock); - ZFS_ACCESSTIME_STAMP(zfsvfs, zp); - + ZFS_ACCESSTIME_STAMP(zsb, zp); zfs_inode_update(zp); - ZFS_EXIT(zfsvfs); + + if (error) { + kmem_free(iov.iov_base, iov.iov_len); + nd_set_link(nd, ERR_PTR(error)); + } else { + nd_set_link(nd, iov.iov_base); + } + + ZFS_EXIT(zsb); return (error); } -EXPORT_SYMBOL(zfs_readlink); +EXPORT_SYMBOL(zfs_follow_link); /* - * Insert a new entry into directory tdvp referencing svp. + * Insert a new entry into directory tdip referencing sip. * - * IN: tdvp - Directory to contain new entry. - * svp - vnode of new entry. + * IN: tdip - Directory to contain new entry. + * sip - inode of new entry. * name - name of new entry. * cr - credentials of caller. - * ct - caller context * * RETURN: 0 if success * error code if failure * * Timestamps: - * tdvp - ctime|mtime updated - * svp - ctime updated + * tdip - ctime|mtime updated + * sip - ctime updated */ /* ARGSUSED */ int -zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, - caller_context_t *ct, int flags) +zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr) { - znode_t *dzp = VTOZ(tdvp); + znode_t *dzp = ITOZ(tdip); znode_t *tzp, *szp; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ITOZSB(tdip); zilog_t *zilog; zfs_dirlock_t *dl; dmu_tx_t *tx; - vnode_t *realvp; int error; int zf = ZNEW; uint64_t parent; uid_t owner; - ASSERT(tdvp->v_type == VDIR); + ASSERT(S_ISDIR(tdip->i_mode)); - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(dzp); - zilog = zfsvfs->z_log; - - if (VOP_REALVP(svp, &realvp, ct) == 0) - svp = realvp; + zilog = zsb->z_log; /* * POSIX dictates that we return EPERM here. * Better choices include ENOTSUP or EISDIR. */ - if (svp->v_type == VDIR) { - ZFS_EXIT(zfsvfs); + if (S_ISDIR(sip->i_mode)) { + ZFS_EXIT(zsb); return (EPERM); } - if (svp->v_vfsp != tdvp->v_vfsp || zfsctl_is_node(svp)) { - ZFS_EXIT(zfsvfs); + if (sip->i_sb != tdip->i_sb) { + ZFS_EXIT(zsb); return (EXDEV); } - szp = VTOZ(svp); + szp = ITOZ(sip); ZFS_VERIFY_ZP(szp); /* Prevent links to .zfs/shares files */ - if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), + if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zsb), &parent, sizeof (uint64_t))) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - if (parent == zfsvfs->z_shares_dir) { - ZFS_EXIT(zfsvfs); + if (parent == zsb->z_shares_dir) { + ZFS_EXIT(zsb); return (EPERM); } - if (zfsvfs->z_utf8 && u8_validate(name, + if (zsb->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EILSEQ); } +#ifdef HAVE_PN_UTILS if (flags & FIGNORECASE) zf |= ZCILOOK; +#endif /* HAVE_PN_UTILS */ /* * We do not support links between attributes and non-attributes @@ -3999,19 +3324,18 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, * imposed in attribute space. */ if ((szp->z_pflags & ZFS_XATTR) != (dzp->z_pflags & ZFS_XATTR)) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } - - owner = zfs_fuid_map_id(zfsvfs, szp->z_uid, cr, ZFS_OWNER); + owner = zfs_fuid_map_id(zsb, szp->z_uid, cr, ZFS_OWNER); if (owner != crgetuid(cr) && secpolicy_basic_link(cr) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EPERM); } if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -4021,11 +3345,11 @@ top: */ error = zfs_dirent_lock(&dl, dzp, name, &tzp, zf, NULL, NULL); if (error) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); zfs_sa_upgrade_txholds(tx, szp); @@ -4039,7 +3363,7 @@ top: goto top; } dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -4047,8 +3371,10 @@ top: if (error == 0) { uint64_t txtype = TX_LINK; +#ifdef HAVE_PN_UTILS if (flags & FIGNORECASE) txtype |= TX_CI; +#endif /* HAVE_PN_UTILS */ zfs_log_link(zilog, tx, txtype, dzp, szp, name); } @@ -4056,16 +3382,12 @@ top: zfs_dirent_unlock(dl); - if (error == 0) { - vnevent_link(svp, ct); - } - - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); zfs_inode_update(dzp); zfs_inode_update(szp); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_link); @@ -4355,7 +3677,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) dmu_tx_abort(tx); } else { mutex_enter(&zp->z_lock); - (void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), + (void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zsb), (void *)&zp->z_atime, sizeof (zp->z_atime), tx); zp->z_atime_dirty = 0; mutex_exit(&zp->z_lock); @@ -4364,14 +3686,14 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) } zfs_zinactive(zp); - rw_exit(&zfsvfs->z_teardown_inactive_lock); + rw_exit(&zsb->z_teardown_inactive_lock); } EXPORT_SYMBOL(zfs_inactive); /* * Bounds-check the seek operation. * - * IN: vp - vnode seeking within + * IN: ip - inode seeking within * ooff - old file offset * noffp - pointer to new file offset * ct - caller context @@ -4380,14 +3702,15 @@ EXPORT_SYMBOL(zfs_inactive); * EINVAL if new offset invalid */ /* ARGSUSED */ -static int -zfs_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, +int +zfs_seek(struct inode *ip, offset_t ooff, offset_t *noffp, caller_context_t *ct) { - if (vp->v_type == VDIR) + if (S_ISDIR(ip->i_mode)) return (0); return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0); } +EXPORT_SYMBOL(zfs_seek); /* * Pre-filter the generic locking function to trap attempts to place @@ -4734,51 +4057,98 @@ zfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, return (0); } +/* + * convoff - converts the given data (start, whence) to the + * given whence. + */ +int +convoff(struct inode *ip, flock64_t *lckdat, int whence, offset_t offset) +{ + struct kstat stat; + int error; + + if ((lckdat->l_whence == 2) || (whence == 2)) { + if ((error = zfs_getattr(ip, &stat, 0, CRED()) != 0)) + return (error); + } + + switch (lckdat->l_whence) { + case 1: + lckdat->l_start += offset; + break; + case 2: + lckdat->l_start += stat.size; + /* FALLTHRU */ + case 0: + break; + default: + return (EINVAL); + } + + if (lckdat->l_start < 0) + return (EINVAL); + + switch (whence) { + case 1: + lckdat->l_start -= offset; + break; + case 2: + lckdat->l_start -= stat.size; + /* FALLTHRU */ + case 0: + break; + default: + return (EINVAL); + } + + lckdat->l_whence = (short)whence; + return (0); +} + /* * Free or allocate space in a file. Currently, this function only * supports the `F_FREESP' command. However, this command is somewhat * misnamed, as its functionality includes the ability to allocate as * well as free space. * - * IN: vp - vnode of file to free data in. + * IN: ip - inode of file to free data in. * cmd - action to take (only F_FREESP supported). * bfp - section of file to free/alloc. * flag - current file open mode flags. * offset - current file offset. * cr - credentials of caller [UNUSED]. - * ct - caller context. * * RETURN: 0 if success * error code if failure * * Timestamps: - * vp - ctime|mtime updated + * ip - ctime|mtime updated */ /* ARGSUSED */ int -zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, - offset_t offset, cred_t *cr, caller_context_t *ct) +zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag, + offset_t offset, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); uint64_t off, len; int error; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); if (cmd != F_FREESP) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } - if ((error = convoff(vp, bfp, 0, offset))) { - ZFS_EXIT(zfsvfs); + if ((error = convoff(ip, bfp, 0, offset))) { + ZFS_EXIT(zsb); return (error); } if (bfp->l_len < 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } @@ -4787,38 +4157,38 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, error = zfs_freesp(zp, off, len, flag, TRUE); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_space); /*ARGSUSED*/ int -zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) +zfs_fid(struct inode *ip, fid_t *fidp) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); uint32_t gen; uint64_t gen64; uint64_t object = zp->z_id; zfid_short_t *zfid; int size, i, error; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zsb), &gen64, sizeof (uint64_t))) != 0) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } gen = (uint32_t)gen64; - size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN; + size = (zsb->z_parent != zsb) ? LONG_FID_LEN : SHORT_FID_LEN; if (fidp->fid_len < size) { fidp->fid_len = size; - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (ENOSPC); } @@ -4836,7 +4206,7 @@ zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i)); if (size == LONG_FID_LEN) { - uint64_t objsetid = dmu_objset_id(zfsvfs->z_os); + uint64_t objsetid = dmu_objset_id(zsb->z_os); zfid_long_t *zlfid; zlfid = (zfid_long_t *)fidp; @@ -4849,95 +4219,24 @@ zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) zlfid->zf_setgen[i] = 0; } - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } EXPORT_SYMBOL(zfs_fid); -static int -zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, - caller_context_t *ct) -{ - znode_t *zp, *xzp; - zfsvfs_t *zfsvfs; - zfs_dirlock_t *dl; - int error; - - switch (cmd) { - case _PC_LINK_MAX: - *valp = ULONG_MAX; - return (0); - - case _PC_FILESIZEBITS: - *valp = 64; - return (0); - - case _PC_XATTR_EXISTS: - zp = VTOZ(vp); - zfsvfs = zp->z_zfsvfs; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); - *valp = 0; - error = zfs_dirent_lock(&dl, zp, "", &xzp, - ZXATTR | ZEXISTS | ZSHARED, NULL, NULL); - if (error == 0) { - zfs_dirent_unlock(dl); - if (!zfs_dirempty(xzp)) - *valp = 1; - VN_RELE(ZTOV(xzp)); - } else if (error == ENOENT) { - /* - * If there aren't extended attributes, it's the - * same as having zero of them. - */ - error = 0; - } - ZFS_EXIT(zfsvfs); - return (error); - - case _PC_SATTR_ENABLED: - case _PC_SATTR_EXISTS: - *valp = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && - (vp->v_type == VREG || vp->v_type == VDIR); - return (0); - - case _PC_ACCESS_FILTERING: - *valp = vfs_has_feature(vp->v_vfsp, VFSFT_ACCESS_FILTER) && - vp->v_type == VDIR; - return (0); - - case _PC_ACL_ENABLED: - *valp = _ACL_ACE_ENABLED; - return (0); - - case _PC_MIN_HOLE_SIZE: - *valp = (ulong_t)SPA_MINBLOCKSIZE; - return (0); - - case _PC_TIMESTAMP_RESOLUTION: - /* nanosecond timestamp resolution */ - *valp = 1L; - return (0); - - default: - return (fs_pathconf(vp, cmd, valp, cr, ct)); - } -} - /*ARGSUSED*/ int -zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, - caller_context_t *ct) +zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); int error; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); error = zfs_getacl(zp, vsecp, skipaclchk, cr); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } @@ -4945,46 +4244,45 @@ EXPORT_SYMBOL(zfs_getsecattr); /*ARGSUSED*/ int -zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, - caller_context_t *ct) +zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); int error; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; - zilog_t *zilog = zfsvfs->z_log; + zilog_t *zilog = zsb->z_log; - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); error = zfs_setacl(zp, vsecp, skipaclchk, cr); - if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (error); } EXPORT_SYMBOL(zfs_setsecattr); +#ifdef HAVE_UIO_ZEROCOPY /* * Tunable, both must be a power of 2. * * zcr_blksz_min: the smallest read we may consider to loan out an arcbuf * zcr_blksz_max: if set to less than the file block size, allow loaning out of - * an arcbuf for a partial block read + * an arcbuf for a partial block read */ int zcr_blksz_min = (1 << 10); /* 1K */ int zcr_blksz_max = (1 << 17); /* 128K */ /*ARGSUSED*/ static int -zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, - caller_context_t *ct) +zfs_reqzcbuf(struct inode *ip, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - int max_blksz = zfsvfs->z_max_blksz; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); + int max_blksz = zsb->z_max_blksz; uio_t *uio = &xuio->xu_uio; ssize_t size = uio->uio_resid; offset_t offset = uio->uio_loffset; @@ -4997,7 +4295,7 @@ zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, if (xuio->xu_type != UIOTYPE_ZEROCOPY) return (EINVAL); - ZFS_ENTER(zfsvfs); + ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); switch (ioflag) { case UIO_WRITE: @@ -5007,7 +4305,7 @@ zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, */ blksz = max_blksz; if (size < blksz || zp->z_blksz != blksz) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } /* @@ -5030,9 +4328,6 @@ zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, fullblk = size / blksz; (void) dmu_xuio_init(xuio, (preamble != 0) + fullblk + (postamble != 0)); - DTRACE_PROBE3(zfs_reqzcbuf_align, int, preamble, - int, postamble, int, - (preamble != 0) + fullblk + (postamble != 0)); /* * Have to fix iov base/len for partial buffers. They @@ -5075,7 +4370,7 @@ zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, blksz = zcr_blksz_max; /* avoid potential complexity of dealing with it */ if (blksz > max_blksz) { - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } @@ -5083,25 +4378,25 @@ zfs_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr, if (size > maxsize) size = maxsize; - if (size < blksz || vn_has_cached_data(vp)) { - ZFS_EXIT(zfsvfs); + if (size < blksz) { + ZFS_EXIT(zsb); return (EINVAL); } break; default: - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (EINVAL); } uio->uio_extflg = UIO_XUIO; XUIO_XUZC_RW(xuio) = ioflag; - ZFS_EXIT(zfsvfs); + ZFS_EXIT(zsb); return (0); } /*ARGSUSED*/ static int -zfs_retzcbuf(vnode_t *vp, xuio_t *xuio, cred_t *cr, caller_context_t *ct) +zfs_retzcbuf(struct inode *ip, xuio_t *xuio, cred_t *cr) { int i; arc_buf_t *abuf; @@ -5124,174 +4419,4 @@ zfs_retzcbuf(vnode_t *vp, xuio_t *xuio, cred_t *cr, caller_context_t *ct) dmu_xuio_fini(xuio); return (0); } - -/* - * Predeclare these here so that the compiler assumes that - * this is an "old style" function declaration that does - * not include arguments => we won't get type mismatch errors - * in the initializations that follow. - */ -static int zfs_inval(); -static int zfs_isdir(); - -static int -zfs_inval() -{ - return (EINVAL); -} - -static int -zfs_isdir() -{ - return (EISDIR); -} -/* - * Directory vnode operations template - */ -vnodeops_t *zfs_dvnodeops; -const fs_operation_def_t zfs_dvnodeops_template[] = { - VOPNAME_OPEN, { .vop_open = zfs_open }, - VOPNAME_CLOSE, { .vop_close = zfs_close }, - VOPNAME_READ, { .error = zfs_isdir }, - VOPNAME_WRITE, { .error = zfs_isdir }, - VOPNAME_IOCTL, { .vop_ioctl = zfs_ioctl }, - VOPNAME_GETATTR, { .vop_getattr = zfs_getattr }, - VOPNAME_SETATTR, { .vop_setattr = zfs_setattr }, - VOPNAME_ACCESS, { .vop_access = zfs_access }, - VOPNAME_LOOKUP, { .vop_lookup = zfs_lookup }, - VOPNAME_CREATE, { .vop_create = zfs_create }, - VOPNAME_REMOVE, { .vop_remove = zfs_remove }, - VOPNAME_LINK, { .vop_link = zfs_link }, - VOPNAME_RENAME, { .vop_rename = zfs_rename }, - VOPNAME_MKDIR, { .vop_mkdir = zfs_mkdir }, - VOPNAME_RMDIR, { .vop_rmdir = zfs_rmdir }, - VOPNAME_READDIR, { .vop_readdir = zfs_readdir }, - VOPNAME_SYMLINK, { .vop_symlink = zfs_symlink }, - VOPNAME_FSYNC, { .vop_fsync = zfs_fsync }, - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_FID, { .vop_fid = zfs_fid }, - VOPNAME_SEEK, { .vop_seek = zfs_seek }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - VOPNAME_GETSECATTR, { .vop_getsecattr = zfs_getsecattr }, - VOPNAME_SETSECATTR, { .vop_setsecattr = zfs_setsecattr }, - VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, - NULL, NULL -}; - -/* - * Regular file vnode operations template - */ -vnodeops_t *zfs_fvnodeops; -const fs_operation_def_t zfs_fvnodeops_template[] = { - VOPNAME_OPEN, { .vop_open = zfs_open }, - VOPNAME_CLOSE, { .vop_close = zfs_close }, - VOPNAME_READ, { .vop_read = zfs_read }, - VOPNAME_WRITE, { .vop_write = zfs_write }, - VOPNAME_IOCTL, { .vop_ioctl = zfs_ioctl }, - VOPNAME_GETATTR, { .vop_getattr = zfs_getattr }, - VOPNAME_SETATTR, { .vop_setattr = zfs_setattr }, - VOPNAME_ACCESS, { .vop_access = zfs_access }, - VOPNAME_LOOKUP, { .vop_lookup = zfs_lookup }, - VOPNAME_RENAME, { .vop_rename = zfs_rename }, - VOPNAME_FSYNC, { .vop_fsync = zfs_fsync }, - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_FID, { .vop_fid = zfs_fid }, - VOPNAME_SEEK, { .vop_seek = zfs_seek }, - VOPNAME_FRLOCK, { .vop_frlock = zfs_frlock }, - VOPNAME_SPACE, { .vop_space = zfs_space }, - VOPNAME_GETPAGE, { .vop_getpage = zfs_getpage }, - VOPNAME_PUTPAGE, { .vop_putpage = zfs_putpage }, - VOPNAME_MAP, { .vop_map = zfs_map }, - VOPNAME_ADDMAP, { .vop_addmap = zfs_addmap }, - VOPNAME_DELMAP, { .vop_delmap = zfs_delmap }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - VOPNAME_GETSECATTR, { .vop_getsecattr = zfs_getsecattr }, - VOPNAME_SETSECATTR, { .vop_setsecattr = zfs_setsecattr }, - VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, - VOPNAME_REQZCBUF, { .vop_reqzcbuf = zfs_reqzcbuf }, - VOPNAME_RETZCBUF, { .vop_retzcbuf = zfs_retzcbuf }, - NULL, NULL -}; - -/* - * Symbolic link vnode operations template - */ -vnodeops_t *zfs_symvnodeops; -const fs_operation_def_t zfs_symvnodeops_template[] = { - VOPNAME_GETATTR, { .vop_getattr = zfs_getattr }, - VOPNAME_SETATTR, { .vop_setattr = zfs_setattr }, - VOPNAME_ACCESS, { .vop_access = zfs_access }, - VOPNAME_RENAME, { .vop_rename = zfs_rename }, - VOPNAME_READLINK, { .vop_readlink = zfs_readlink }, - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_FID, { .vop_fid = zfs_fid }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, - NULL, NULL -}; - -/* - * special share hidden files vnode operations template - */ -vnodeops_t *zfs_sharevnodeops; -const fs_operation_def_t zfs_sharevnodeops_template[] = { - VOPNAME_GETATTR, { .vop_getattr = zfs_getattr }, - VOPNAME_ACCESS, { .vop_access = zfs_access }, - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_FID, { .vop_fid = zfs_fid }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - VOPNAME_GETSECATTR, { .vop_getsecattr = zfs_getsecattr }, - VOPNAME_SETSECATTR, { .vop_setsecattr = zfs_setsecattr }, - VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, - NULL, NULL -}; - -/* - * Extended attribute directory vnode operations template - * This template is identical to the directory vnodes - * operation template except for restricted operations: - * VOP_MKDIR() - * VOP_SYMLINK() - * Note that there are other restrictions embedded in: - * zfs_create() - restrict type to VREG - * zfs_link() - no links into/out of attribute space - * zfs_rename() - no moves into/out of attribute space - */ -vnodeops_t *zfs_xdvnodeops; -const fs_operation_def_t zfs_xdvnodeops_template[] = { - VOPNAME_OPEN, { .vop_open = zfs_open }, - VOPNAME_CLOSE, { .vop_close = zfs_close }, - VOPNAME_IOCTL, { .vop_ioctl = zfs_ioctl }, - VOPNAME_GETATTR, { .vop_getattr = zfs_getattr }, - VOPNAME_SETATTR, { .vop_setattr = zfs_setattr }, - VOPNAME_ACCESS, { .vop_access = zfs_access }, - VOPNAME_LOOKUP, { .vop_lookup = zfs_lookup }, - VOPNAME_CREATE, { .vop_create = zfs_create }, - VOPNAME_REMOVE, { .vop_remove = zfs_remove }, - VOPNAME_LINK, { .vop_link = zfs_link }, - VOPNAME_RENAME, { .vop_rename = zfs_rename }, - VOPNAME_MKDIR, { .error = zfs_inval }, - VOPNAME_RMDIR, { .vop_rmdir = zfs_rmdir }, - VOPNAME_READDIR, { .vop_readdir = zfs_readdir }, - VOPNAME_SYMLINK, { .error = zfs_inval }, - VOPNAME_FSYNC, { .vop_fsync = zfs_fsync }, - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_FID, { .vop_fid = zfs_fid }, - VOPNAME_SEEK, { .vop_seek = zfs_seek }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - VOPNAME_GETSECATTR, { .vop_getsecattr = zfs_getsecattr }, - VOPNAME_SETSECATTR, { .vop_setsecattr = zfs_setsecattr }, - VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, - NULL, NULL -}; - -/* - * Error vnode operations template - */ -vnodeops_t *zfs_evnodeops; -const fs_operation_def_t zfs_evnodeops_template[] = { - VOPNAME_INACTIVE, { .vop_inactive = zfs_inactive }, - VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, - NULL, NULL -}; -#endif /* HAVE_ZPL */ +#endif /* HAVE_UIO_ZEROCOPY */ diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 283b4d511..024668287 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -51,9 +51,11 @@ #include #include #include +#include #include #include #include +#include #endif /* _KERNEL */ #include @@ -88,11 +90,6 @@ * (such as VFS logic) that will not compile easily in userland. */ #ifdef _KERNEL -/* - * Needed to close a small window in zfs_znode_move() that allows the zfsvfs to - * be freed before it can be safely accessed. - */ -krwlock_t zfsvfs_lock; static kmem_cache_t *znode_cache = NULL; @@ -102,14 +99,7 @@ zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) { znode_t *zp = buf; - ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); - - zp->z_vnode = vn_alloc(kmflags); - if (zp->z_vnode == NULL) { - return (-1); - } - ZTOV(zp)->v_data = zp; - + inode_init_once(ZTOI(zp)); list_link_init(&zp->z_link_node); mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); @@ -133,9 +123,6 @@ zfs_znode_cache_destructor(void *buf, void *arg) { znode_t *zp = buf; - ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); - ASSERT(ZTOV(zp)->v_data == zp); - vn_free(ZTOV(zp)); ASSERT(!list_link_active(&zp->z_link_node)); mutex_destroy(&zp->z_lock); rw_destroy(&zp->z_parent_lock); @@ -154,11 +141,10 @@ zfs_znode_init(void) /* * Initialize zcache */ - rw_init(&zfsvfs_lock, NULL, RW_DEFAULT, NULL); ASSERT(znode_cache == NULL); znode_cache = kmem_cache_create("zfs_znode_cache", sizeof (znode_t), 0, zfs_znode_cache_constructor, - zfs_znode_cache_destructor, NULL, NULL, NULL, 0); + zfs_znode_cache_destructor, NULL, NULL, NULL, KMC_KMEM); } void @@ -170,12 +156,10 @@ zfs_znode_fini(void) if (znode_cache) kmem_cache_destroy(znode_cache); znode_cache = NULL; - rw_destroy(&zfsvfs_lock); } -#ifdef HAVE_ZPL int -zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) +zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx) { #ifdef HAVE_SHARE zfs_acl_ids_t acl_ids; @@ -186,13 +170,11 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) int error; vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; - vattr.va_type = VDIR; - vattr.va_mode = S_IFDIR|0555; + vattr.va_mode = S_IFDIR | 0555; vattr.va_uid = crgetuid(kcred); vattr.va_gid = crgetgid(kcred); sharezp = kmem_cache_alloc(znode_cache, KM_SLEEP); - ASSERT(!POINTER_IS_VALID(sharezp->z_zfsvfs)); sharezp->z_moved = 0; sharezp->z_unlinked = 0; sharezp->z_atime_dirty = 0; @@ -214,7 +196,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) zfsvfs->z_shares_dir = sharezp->z_id; zfs_acl_ids_free(&acl_ids); - ZTOV(sharezp)->v_count = 0; + // ZTOV(sharezp)->v_count = 0; sa_handle_destroy(sharezp->z_sa_hdl); kmem_cache_free(znode_cache, sharezp); @@ -238,8 +220,6 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) #define MAXMIN64 0xffffffffUL #endif -#endif /* HAVE_ZPL */ - /* * Create special expldev for ZFS private use. * Can't use standard expldev since it doesn't do @@ -260,42 +240,18 @@ zfs_expldev(dev_t dev) #endif } -/* - * Special cmpldev for ZFS private use. - * Can't use standard cmpldev since it takes - * a long dev_t and compresses it to dev32_t in - * LP64. We need to do a compaction of a long dev_t - * to a dev32_t in ILP32. - */ -dev_t -zfs_cmpldev(uint64_t dev) -{ -#ifndef _LP64 - minor_t minor = (minor_t)dev & MAXMIN64; - major_t major = (major_t)(dev >> NBITSMINOR64) & MAXMAJ64; - - if (major > MAXMAJ32 || minor > MAXMIN32) - return (NODEV32); - - return (((dev32_t)major << NBITSMINOR32) | minor); -#else - return (dev); -#endif -} - static void -zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp, +zfs_znode_sa_init(zfs_sb_t *zsb, znode_t *zp, dmu_buf_t *db, dmu_object_type_t obj_type, sa_handle_t *sa_hdl) { - ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs)); - ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id))); + ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zsb, zp->z_id))); mutex_enter(&zp->z_lock); ASSERT(zp->z_sa_hdl == NULL); ASSERT(zp->z_acl_cached == NULL); if (sa_hdl == NULL) { - VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, zp, + VERIFY(0 == sa_handle_get_from_db(zsb->z_os, db, zp, SA_HDL_SHARED, &zp->z_sa_hdl)); } else { zp->z_sa_hdl = sa_hdl; @@ -304,60 +260,119 @@ zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp, zp->z_is_sa = (obj_type == DMU_OT_SA) ? B_TRUE : B_FALSE; - /* - * Slap on VROOT if we are the root znode - */ - if (zp->z_id == zfsvfs->z_root) - ZTOV(zp)->v_flag |= VROOT; - mutex_exit(&zp->z_lock); - vn_exists(ZTOV(zp)); } void zfs_znode_dmu_fini(znode_t *zp) { - ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp->z_zfsvfs, zp->z_id)) || + ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(ZTOZSB(zp), zp->z_id)) || zp->z_unlinked || - RW_WRITE_HELD(&zp->z_zfsvfs->z_teardown_inactive_lock)); + RW_WRITE_HELD(&ZTOZSB(zp)->z_teardown_inactive_lock)); sa_handle_destroy(zp->z_sa_hdl); zp->z_sa_hdl = NULL; } /* - * Construct a new znode+inode and initialize. + * Called by new_inode() to allocate a new inode. + */ +int +zfs_inode_alloc(struct super_block *sb, struct inode **ip) +{ + znode_t *zp; + + zp = kmem_cache_alloc(znode_cache, KM_SLEEP); + *ip = ZTOI(zp); + + return (0); +} + +/* + * Called in multiple places when an inode should be destroyed. + */ +void +zfs_inode_destroy(struct inode *ip) +{ + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ZTOZSB(zp); + + mutex_enter(&zsb->z_znodes_lock); + list_remove(&zsb->z_all_znodes, zp); + mutex_exit(&zsb->z_znodes_lock); + + if (zp->z_acl_cached) { + zfs_acl_free(zp->z_acl_cached); + zp->z_acl_cached = NULL; + } + + kmem_cache_free(znode_cache, zp); +} + +static void +zfs_inode_set_ops(zfs_sb_t *zsb, struct inode *ip) +{ + uint64_t rdev; + + switch (ip->i_mode & S_IFMT) { + case S_IFREG: + ip->i_op = &zpl_inode_operations; + ip->i_fop = &zpl_file_operations; + ip->i_mapping->a_ops = &zpl_address_space_operations; + break; + + case S_IFDIR: + ip->i_op = &zpl_dir_inode_operations; + ip->i_fop = &zpl_dir_file_operations; + ITOZ(ip)->z_zn_prefetch = B_TRUE; + break; + + case S_IFLNK: + ip->i_op = &zpl_symlink_inode_operations; + break; + + case S_IFCHR: + case S_IFBLK: + case S_IFIFO: + case S_IFSOCK: + VERIFY(sa_lookup(ITOZ(ip)->z_sa_hdl, SA_ZPL_RDEV(zsb), + &rdev, sizeof (rdev)) == 0); + init_special_inode(ip, ip->i_mode, rdev); + ip->i_op = &zpl_special_inode_operations; + break; + + default: + printk("ZFS: Invalid mode: 0x%x\n", ip->i_mode); + VERIFY(0); + } +} + +/* + * Construct a znode+inode and initialize. * * This does not do a call to dmu_set_user() that is * up to the caller to do, in case you don't want to * return the znode */ static znode_t * -zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, - dmu_object_type_t obj_type, sa_handle_t *hdl) +zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz, + dmu_object_type_t obj_type, uint64_t obj, sa_handle_t *hdl) { znode_t *zp; - struct inode *inode; + struct inode *ip; uint64_t parent; sa_bulk_attr_t bulk[9]; int count = 0; - ASSERT(zfsvfs != NULL); - ASSERT(zfsvfs->z_vfs != NULL); - ASSERT(zfsvfs->z_vfs->mnt_sb != NULL); + ASSERT(zsb != NULL); - inode = iget_locked(zfsvfs->z_vfs->mnt_sb, db->db_object); - zp = ITOZ(inode); + ip = new_inode(zsb->z_sb); + if (ip == NULL) + return (NULL); - ASSERT(inode->i_state & I_NEW); + zp = ITOZ(ip); ASSERT(zp->z_dirlocks == NULL); - ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); zp->z_moved = 0; - - /* - * Defer setting z_zfsvfs until the znode is ready to be a candidate for - * the zfs_znode_move() callback. - */ zp->z_sa_hdl = NULL; zp->z_unlinked = 0; zp->z_atime_dirty = 0; @@ -367,59 +382,48 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, zp->z_seq = 0x7A4653; zp->z_sync_cnt = 0; - zfs_znode_sa_init(zfsvfs, zp, db, obj_type, hdl); + zfs_znode_sa_init(zsb, zp, db, obj_type, hdl); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, - &zp->z_mode, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, - &zp->z_gen, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, - &zp->z_size, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, - &zp->z_links, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &zp->z_mode, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL, &zp->z_atime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, - &zp->z_uid, 8); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, - &zp->z_gid, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &zp->z_uid, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &zp->z_gid, 8); if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) { if (hdl == NULL) sa_handle_destroy(zp->z_sa_hdl); - iput(inode); - return (NULL); + + goto error; } - inode->i_mode = (umode_t)zp->z_mode; - if ((S_ISCHR(inode->i_mode)) || (S_ISBLK(inode->i_mode))) { - uint64_t rdev; - VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs), - &rdev, sizeof (rdev)) == 0); - inode->i_rdev = zfs_cmpldev(rdev); - } + ip->i_ino = obj; + ip->i_mode = zp->z_mode; + ip->i_mtime = ip->i_atime = ip->i_ctime = CURRENT_TIME_SEC; + zfs_inode_set_ops(zsb, ip); - /* zp->z_set_ops_inode() must be set in sb->alloc_inode() */ - ASSERT(zp->z_set_ops_inode != NULL); - zp->z_set_ops_inode(inode); - unlock_new_inode(inode); + if (insert_inode_locked(ip)) + goto error; - mutex_enter(&zfsvfs->z_znodes_lock); - list_insert_tail(&zfsvfs->z_all_znodes, zp); + mutex_enter(&zsb->z_znodes_lock); + list_insert_tail(&zsb->z_all_znodes, zp); membar_producer(); - /* - * Everything else must be valid before assigning z_zfsvfs makes the - * znode eligible for zfs_znode_move(). - */ - zp->z_zfsvfs = zfsvfs; - mutex_exit(&zfsvfs->z_znodes_lock); + mutex_exit(&zsb->z_znodes_lock); - VFS_HOLD(zfsvfs->z_vfs); + unlock_new_inode(ip); return (zp); + +error: + unlock_new_inode(ip); + iput(ip); + return NULL; } /* @@ -432,35 +436,35 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, void zfs_inode_update(znode_t *zp) { - zfsvfs_t *zfsvfs; - struct inode *inode; + zfs_sb_t *zsb; + struct inode *ip; uint32_t blksize; uint64_t atime[2], mtime[2], ctime[2]; ASSERT(zp != NULL); - zfsvfs = zp->z_zfsvfs; - inode = ZTOI(zp); + zsb = ZTOZSB(zp); + ip = ZTOI(zp); - sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), &atime, 16); - sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zfsvfs), &mtime, 16); - sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zfsvfs), &ctime, 16); + sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zsb), &atime, 16); + sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zsb), &mtime, 16); + sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zsb), &ctime, 16); - spin_lock(&inode->i_lock); - inode->i_generation = zp->z_gen; - inode->i_uid = zp->z_uid; - inode->i_gid = zp->z_gid; - inode->i_nlink = zp->z_links; - inode->i_mode = zp->z_mode; - inode->i_blkbits = SPA_MINBLOCKSHIFT; + spin_lock(&ip->i_lock); + ip->i_generation = zp->z_gen; + ip->i_uid = zp->z_uid; + ip->i_gid = zp->z_gid; + ip->i_nlink = zp->z_links; + ip->i_mode = zp->z_mode; + ip->i_blkbits = SPA_MINBLOCKSHIFT; dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, - (u_longlong_t *)&inode->i_blocks); + (u_longlong_t *)&ip->i_blocks); - ZFS_TIME_DECODE(&inode->i_atime, atime); - ZFS_TIME_DECODE(&inode->i_mtime, mtime); - ZFS_TIME_DECODE(&inode->i_ctime, ctime); + ZFS_TIME_DECODE(&ip->i_atime, atime); + ZFS_TIME_DECODE(&ip->i_mtime, mtime); + ZFS_TIME_DECODE(&ip->i_ctime, ctime); - i_size_write(inode, zp->z_size); - spin_unlock(&inode->i_lock); + i_size_write(ip, zp->z_size); + spin_unlock(&ip->i_lock); } static uint64_t empty_xattr; @@ -491,7 +495,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, uint64_t mode, size, links, parent, pflags; uint64_t dzp_pflags = 0; uint64_t rdev = 0; - zfsvfs_t *zfsvfs = dzp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(dzp); dmu_buf_t *db; timestruc_t now; uint64_t gen, obj; @@ -503,9 +507,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, int cnt = 0; zfs_acl_locator_cb_t locate = { 0 }; - ASSERT(vap && (vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE)); - - if (zfsvfs->z_replay) { + if (zsb->z_replay) { obj = vap->va_nodeid; now = vap->va_ctime; /* see zfs_replay_create() */ gen = vap->va_nblocks; /* ditto */ @@ -515,7 +517,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, gen = dmu_tx_get_txg(tx); } - obj_type = zfsvfs->z_use_sa ? DMU_OT_SA : DMU_OT_ZNODE; + obj_type = zsb->z_use_sa ? DMU_OT_SA : DMU_OT_ZNODE; bonuslen = (obj_type == DMU_OT_SA) ? DN_MAX_BONUSLEN : ZFS_OLD_ZNODE_PHYS_SIZE; @@ -528,32 +530,32 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, * that there will be an i/o error and we will fail one of the * assertions below. */ - if (vap->va_type == VDIR) { - if (zfsvfs->z_replay) { - err = zap_create_claim_norm(zfsvfs->z_os, obj, - zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, + if (S_ISDIR(vap->va_mode)) { + if (zsb->z_replay) { + err = zap_create_claim_norm(zsb->z_os, obj, + zsb->z_norm, DMU_OT_DIRECTORY_CONTENTS, obj_type, bonuslen, tx); ASSERT3U(err, ==, 0); } else { - obj = zap_create_norm(zfsvfs->z_os, - zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, + obj = zap_create_norm(zsb->z_os, + zsb->z_norm, DMU_OT_DIRECTORY_CONTENTS, obj_type, bonuslen, tx); } } else { - if (zfsvfs->z_replay) { - err = dmu_object_claim(zfsvfs->z_os, obj, + if (zsb->z_replay) { + err = dmu_object_claim(zsb->z_os, obj, DMU_OT_PLAIN_FILE_CONTENTS, 0, obj_type, bonuslen, tx); ASSERT3U(err, ==, 0); } else { - obj = dmu_object_alloc(zfsvfs->z_os, + obj = dmu_object_alloc(zsb->z_os, DMU_OT_PLAIN_FILE_CONTENTS, 0, obj_type, bonuslen, tx); } } - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); - VERIFY(0 == sa_buf_hold(zfsvfs->z_os, obj, NULL, &db)); + ZFS_OBJ_HOLD_ENTER(zsb, obj); + VERIFY(0 == sa_buf_hold(zsb->z_os, obj, NULL, &db)); /* * If this is the root, fix up the half-initialized parent pointer @@ -572,21 +574,20 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, flag |= IS_XATTR; } - if (zfsvfs->z_use_fuids) + if (zsb->z_use_fuids) pflags = ZFS_ARCHIVE | ZFS_AV_MODIFIED; else pflags = 0; - if (vap->va_type == VDIR) { + if (S_ISDIR(vap->va_mode)) { size = 2; /* contents ("." and "..") */ links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1; } else { size = links = 0; } - if (vap->va_type == VBLK || vap->va_type == VCHR) { + if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode)) rdev = zfs_expldev(vap->va_rdev); - } parent = dzp->z_id; mode = acl_ids->z_mode; @@ -603,20 +604,20 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, ZFS_TIME_ENCODE(&now, crtime); ZFS_TIME_ENCODE(&now, ctime); - if (vap->va_mask & AT_ATIME) { + if (vap->va_mask & ATTR_ATIME) { ZFS_TIME_ENCODE(&vap->va_atime, atime); } else { ZFS_TIME_ENCODE(&now, atime); } - if (vap->va_mask & AT_MTIME) { + if (vap->va_mask & ATTR_MTIME) { ZFS_TIME_ENCODE(&vap->va_mtime, mtime); } else { ZFS_TIME_ENCODE(&now, mtime); } /* Now add in all of the "SA" attributes */ - VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED, + VERIFY(0 == sa_handle_get_from_db(zsb->z_os, db, NULL, SA_HDL_SHARED, &sa_hdl)); /* @@ -628,75 +629,75 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, sa_attrs = kmem_alloc(sizeof(sa_bulk_attr_t) * ZPL_END, KM_SLEEP); if (obj_type == DMU_OT_ZNODE) { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zsb), NULL, &atime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zsb), NULL, &gen, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zsb), NULL, &mode, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zsb), NULL, &size, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zsb), NULL, &parent, 8); } else { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zsb), NULL, &mode, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zsb), NULL, &size, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zsb), NULL, &gen, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zfsvfs), NULL, - &acl_ids->z_fuid, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zfsvfs), NULL, - &acl_ids->z_fgid, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zsb), + NULL, &acl_ids->z_fuid, 8); + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zsb), + NULL, &acl_ids->z_fgid, 8); + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zsb), NULL, &parent, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zsb), NULL, &pflags, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zsb), NULL, &atime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zsb), NULL, &mtime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zsb), NULL, &ctime, 16); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16); } - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_LINKS(zfsvfs), NULL, &links, 8); + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_LINKS(zsb), NULL, &links, 8); if (obj_type == DMU_OT_ZNODE) { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_XATTR(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_XATTR(zsb), NULL, &empty_xattr, 8); } if (obj_type == DMU_OT_ZNODE || - (vap->va_type == VBLK || vap->va_type == VCHR)) { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zfsvfs), + (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))) { + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zsb), NULL, &rdev, 8); } if (obj_type == DMU_OT_ZNODE) { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zsb), NULL, &pflags, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zsb), NULL, &acl_ids->z_fuid, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zsb), NULL, &acl_ids->z_fgid, 8); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PAD(zfsvfs), NULL, pad, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PAD(zsb), NULL, pad, sizeof (uint64_t) * 4); - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ZNODE_ACL(zsb), NULL, &acl_phys, sizeof (zfs_acl_phys_t)); } else if (acl_ids->z_aclp->z_version >= ZFS_ACL_VERSION_FUID) { - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_COUNT(zfsvfs), NULL, + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_COUNT(zsb), NULL, &acl_ids->z_aclp->z_acl_count, 8); locate.cb_aclp = acl_ids->z_aclp; - SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_ACES(zfsvfs), + SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_ACES(zsb), zfs_acl_data_locator, &locate, acl_ids->z_aclp->z_acl_bytes); mode = zfs_mode_compute(mode, acl_ids->z_aclp, &pflags, @@ -706,8 +707,11 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0); if (!(flag & IS_ROOT_NODE)) { - *zpp = zfs_znode_alloc(zfsvfs, db, 0, obj_type, sa_hdl); + *zpp = zfs_znode_alloc(zsb, db, 0, obj_type, obj, sa_hdl); ASSERT(*zpp != NULL); + ASSERT(dzp != NULL); + err = zpl_xattr_security_init(ZTOI(*zpp), ZTOI(dzp)); + ASSERT3S(err, ==, 0); } else { /* * If we are creating the root node, the "parent" we @@ -721,118 +725,17 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, (*zpp)->z_pflags = pflags; (*zpp)->z_mode = mode; - if (vap->va_mask & AT_XVATTR) - zfs_xvattr_set(*zpp, (xvattr_t *)vap, tx); - if (obj_type == DMU_OT_ZNODE || acl_ids->z_aclp->z_version < ZFS_ACL_VERSION_FUID) { err = zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx); ASSERT3S(err, ==, 0); } kmem_free(sa_attrs, sizeof(sa_bulk_attr_t) * ZPL_END); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); -} - -/* - * zfs_xvattr_set only updates the in-core attributes - * it is assumed the caller will be doing an sa_bulk_update - * to push the changes out - */ -void -zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) -{ -#ifdef HAVE_XVATTR - xoptattr_t *xoap; - - xoap = xva_getxoptattr(xvap); - ASSERT(xoap); - - if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { - uint64_t times[2]; - ZFS_TIME_ENCODE(&xoap->xoa_createtime, times); - (void) sa_update(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), - ×, sizeof (times), tx); - XVA_SET_RTN(xvap, XAT_CREATETIME); - } - if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { - ZFS_ATTR_SET(zp, ZFS_READONLY, xoap->xoa_readonly, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_READONLY); - } - if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { - ZFS_ATTR_SET(zp, ZFS_HIDDEN, xoap->xoa_hidden, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_HIDDEN); - } - if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { - ZFS_ATTR_SET(zp, ZFS_SYSTEM, xoap->xoa_system, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_SYSTEM); - } - if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { - ZFS_ATTR_SET(zp, ZFS_ARCHIVE, xoap->xoa_archive, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_ARCHIVE); - } - if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) { - ZFS_ATTR_SET(zp, ZFS_IMMUTABLE, xoap->xoa_immutable, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_IMMUTABLE); - } - if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { - ZFS_ATTR_SET(zp, ZFS_NOUNLINK, xoap->xoa_nounlink, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_NOUNLINK); - } - if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) { - ZFS_ATTR_SET(zp, ZFS_APPENDONLY, xoap->xoa_appendonly, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_APPENDONLY); - } - if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { - ZFS_ATTR_SET(zp, ZFS_NODUMP, xoap->xoa_nodump, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_NODUMP); - } - if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) { - ZFS_ATTR_SET(zp, ZFS_OPAQUE, xoap->xoa_opaque, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_OPAQUE); - } - if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { - ZFS_ATTR_SET(zp, ZFS_AV_QUARANTINED, - xoap->xoa_av_quarantined, zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_AV_QUARANTINED); - } - if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) { - ZFS_ATTR_SET(zp, ZFS_AV_MODIFIED, xoap->xoa_av_modified, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_AV_MODIFIED); - } - if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { - zfs_sa_set_scanstamp(zp, xvap, tx); - XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP); - } - if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) { - ZFS_ATTR_SET(zp, ZFS_REPARSE, xoap->xoa_reparse, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_REPARSE); - } - if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) { - ZFS_ATTR_SET(zp, ZFS_OFFLINE, xoap->xoa_offline, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_OFFLINE); - } - if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) { - ZFS_ATTR_SET(zp, ZFS_SPARSE, xoap->xoa_sparse, - zp->z_pflags, tx); - XVA_SET_RTN(xvap, XAT_SPARSE); - } -#endif /* HAVE_XVATTR */ + ZFS_OBJ_HOLD_EXIT(zsb, obj); } int -zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) +zfs_zget(zfs_sb_t *zsb, uint64_t obj_num, znode_t **zpp) { dmu_object_info_t doi; dmu_buf_t *db; @@ -842,11 +745,11 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) *zpp = NULL; - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); + ZFS_OBJ_HOLD_ENTER(zsb, obj_num); - err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); + err = sa_buf_hold(zsb->z_os, obj_num, NULL, &db); if (err) { - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (err); } @@ -856,7 +759,7 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) (doi.doi_bonus_type == DMU_OT_ZNODE && doi.doi_bonus_size < sizeof (znode_phys_t)))) { sa_buf_rele(db, NULL); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (EINVAL); } @@ -878,19 +781,18 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) if (zp->z_unlinked) { err = ENOENT; } else { - VN_HOLD(ZTOV(zp)); + igrab(ZTOI(zp)); *zpp = zp; err = 0; } sa_buf_rele(db, NULL); mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (err); } /* - * Not found create new znode/vnode - * but only if file exists. + * Not found create new znode/vnode but only if file exists. * * There is a small window where zfs_vget() could * find this object while a file create is still in @@ -899,21 +801,21 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) * if zfs_znode_alloc() fails it will drop the hold on the * bonus buffer. */ - zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size, - doi.doi_bonus_type, NULL); + zp = zfs_znode_alloc(zsb, db, doi.doi_data_block_size, + doi.doi_bonus_type, obj_num, NULL); if (zp == NULL) { err = ENOENT; } else { *zpp = zp; } - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (err); } int zfs_rezget(znode_t *zp) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); dmu_object_info_t doi; dmu_buf_t *db; uint64_t obj_num = zp->z_id; @@ -923,7 +825,7 @@ zfs_rezget(znode_t *zp) int count = 0; uint64_t gen; - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); + ZFS_OBJ_HOLD_ENTER(zsb, obj_num); mutex_enter(&zp->z_acl_lock); if (zp->z_acl_cached) { @@ -933,9 +835,9 @@ zfs_rezget(znode_t *zp) mutex_exit(&zp->z_acl_lock); ASSERT(zp->z_sa_hdl == NULL); - err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); + err = sa_buf_hold(zsb->z_os, obj_num, NULL, &db); if (err) { - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (err); } @@ -945,33 +847,33 @@ zfs_rezget(znode_t *zp) (doi.doi_bonus_type == DMU_OT_ZNODE && doi.doi_bonus_size < sizeof (znode_phys_t)))) { sa_buf_rele(db, NULL); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (EINVAL); } - zfs_znode_sa_init(zfsvfs, zp, db, doi.doi_bonus_type, NULL); + zfs_znode_sa_init(zsb, zp, db, doi.doi_bonus_type, NULL); /* reload cached values */ - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &gen, sizeof (gen)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, sizeof (zp->z_size)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, sizeof (zp->z_links)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, sizeof (zp->z_pflags)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL, &zp->z_atime, sizeof (zp->z_atime)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &zp->z_uid, sizeof (zp->z_uid)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &zp->z_gid, sizeof (zp->z_gid)); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, sizeof (mode)); if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) { zfs_znode_dmu_fini(zp); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (EIO); } @@ -979,14 +881,14 @@ zfs_rezget(znode_t *zp) if (gen != zp->z_gen) { zfs_znode_dmu_fini(zp); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (EIO); } zp->z_unlinked = (zp->z_links == 0); zp->z_blksz = doi.doi_data_block_size; - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + ZFS_OBJ_HOLD_EXIT(zsb, obj_num); return (0); } @@ -994,27 +896,25 @@ zfs_rezget(znode_t *zp) void zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - objset_t *os = zfsvfs->z_os; + zfs_sb_t *zsb = ZTOZSB(zp); + objset_t *os = zsb->z_os; uint64_t obj = zp->z_id; uint64_t acl_obj = zfs_external_acl(zp); - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); + ZFS_OBJ_HOLD_ENTER(zsb, obj); if (acl_obj) { VERIFY(!zp->z_is_sa); VERIFY(0 == dmu_object_free(os, acl_obj, tx)); } VERIFY(0 == dmu_object_free(os, obj, tx)); zfs_znode_dmu_fini(zp); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); - zfs_znode_free(zp); + ZFS_OBJ_HOLD_EXIT(zsb, obj); } void zfs_zinactive(znode_t *zp) { - vnode_t *vp = ZTOV(zp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); uint64_t z_id = zp->z_id; ASSERT(zp->z_sa_hdl); @@ -1022,29 +922,8 @@ zfs_zinactive(znode_t *zp) /* * Don't allow a zfs_zget() while were trying to release this znode */ - ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id); - + ZFS_OBJ_HOLD_ENTER(zsb, z_id); mutex_enter(&zp->z_lock); - mutex_enter(&vp->v_lock); - vp->v_count--; - if (vp->v_count > 0 || vn_has_cached_data(vp)) { - /* - * If the hold count is greater than zero, somebody has - * obtained a new reference on this znode while we were - * processing it here, so we are done. If we still have - * mapped pages then we are also done, since we don't - * want to inactivate the znode until the pages get pushed. - * - * XXX - if vn_has_cached_data(vp) is true, but count == 0, - * this seems like it would leave the znode hanging with - * no chance to go inactive... - */ - mutex_exit(&vp->v_lock); - mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); - return; - } - mutex_exit(&vp->v_lock); /* * If this was the last reference to a file with no links, @@ -1052,39 +931,14 @@ zfs_zinactive(znode_t *zp) */ if (zp->z_unlinked) { mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); + ZFS_OBJ_HOLD_EXIT(zsb, z_id); zfs_rmnode(zp); return; } mutex_exit(&zp->z_lock); zfs_znode_dmu_fini(zp); - ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); - zfs_znode_free(zp); -} - -void -zfs_znode_free(znode_t *zp) -{ - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - - vn_invalid(ZTOV(zp)); - - ASSERT(ZTOV(zp)->v_count == 0); - - mutex_enter(&zfsvfs->z_znodes_lock); - POINTER_INVALIDATE(&zp->z_zfsvfs); - list_remove(&zfsvfs->z_all_znodes, zp); - mutex_exit(&zfsvfs->z_znodes_lock); - - if (zp->z_acl_cached) { - zfs_acl_free(zp->z_acl_cached); - zp->z_acl_cached = NULL; - } - - kmem_cache_free(znode_cache, zp); - - VFS_RELE(zfsvfs->z_vfs); + ZFS_OBJ_HOLD_EXIT(zsb, z_id); } void @@ -1102,21 +956,21 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2], zp->z_atime_dirty = 1; } - if (flag & AT_ATIME) { + if (flag & ATTR_ATIME) { ZFS_TIME_ENCODE(&now, zp->z_atime); } - if (flag & AT_MTIME) { + if (flag & ATTR_MTIME) { ZFS_TIME_ENCODE(&now, mtime); - if (zp->z_zfsvfs->z_use_fuids) { + if (ZTOZSB(zp)->z_use_fuids) { zp->z_pflags |= (ZFS_ARCHIVE | ZFS_AV_MODIFIED); } } - if (flag & AT_CTIME) { + if (flag & ATTR_CTIME) { ZFS_TIME_ENCODE(&now, ctime); - if (zp->z_zfsvfs->z_use_fuids) + if (ZTOZSB(zp)->z_use_fuids) zp->z_pflags |= ZFS_ARCHIVE; } } @@ -1146,7 +1000,7 @@ zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) if (zp->z_blksz && zp->z_size > zp->z_blksz) return; - error = dmu_object_set_blocksize(zp->z_zfsvfs->z_os, zp->z_id, + error = dmu_object_set_blocksize(ZTOZSB(zp)->z_os, zp->z_id, size, 0, tx); if (error == ENOTSUP) @@ -1157,7 +1011,7 @@ zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy); } -#ifdef HAVE_ZPL +#ifdef HAVE_MMAP /* * This is a dummy interface used when pvn_vplist_dirty() should *not* * be calling back into the fs for a putpage(). E.g.: when truncating @@ -1171,7 +1025,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, ASSERT(0); return (0); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_MMAP */ /* * Increase the file length @@ -1185,7 +1039,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, static int zfs_extend(znode_t *zp, uint64_t end) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); dmu_tx_t *tx; rl_t *rl; uint64_t newblksz; @@ -1204,19 +1058,19 @@ zfs_extend(znode_t *zp, uint64_t end) return (0); } top: - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); if (end > zp->z_blksz && - (!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) { + (!ISP2(zp->z_blksz) || zp->z_blksz < zsb->z_max_blksz)) { /* * We are growing the file past the current block size. */ - if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { + if (zp->z_blksz > ZTOZSB(zp)->z_max_blksz) { ASSERT(!ISP2(zp->z_blksz)); newblksz = MIN(end, SPA_MAXBLOCKSIZE); } else { - newblksz = MIN(end, zp->z_zfsvfs->z_max_blksz); + newblksz = MIN(end, ZTOZSB(zp)->z_max_blksz); } dmu_tx_hold_write(tx, zp->z_id, 0, newblksz); } else { @@ -1240,7 +1094,7 @@ top: zp->z_size = end; - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zp->z_zfsvfs), + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(ZTOZSB(zp)), &zp->z_size, sizeof (zp->z_size), tx)); zfs_range_unlock(rl); @@ -1257,13 +1111,13 @@ top: * off - start of section to free. * len - length of section to free. * - * RETURN: 0 if success + * RETURN: 0 if success * error code if failure */ static int zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zfs_sb_t *zsb = ZTOZSB(zp); rl_t *rl; int error; @@ -1283,7 +1137,7 @@ zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) if (off + len > zp->z_size) len = zp->z_size - off; - error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, off, len); + error = dmu_free_long_range(zsb->z_os, zp->z_id, off, len); zfs_range_unlock(rl); @@ -1296,16 +1150,13 @@ zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) * IN: zp - znode of file to free data in. * end - new end-of-file. * - * RETURN: 0 if success + * RETURN: 0 if success * error code if failure */ static int zfs_trunc(znode_t *zp, uint64_t end) { - zfsvfs_t *zfsvfs = zp->z_zfsvfs; -#ifdef HAVE_ZPL - vnode_t *vp = ZTOV(zp); -#endif /* HAVE_ZPL */ + zfs_sb_t *zsb = ZTOZSB(zp); dmu_tx_t *tx; rl_t *rl; int error; @@ -1325,13 +1176,13 @@ zfs_trunc(znode_t *zp, uint64_t end) return (0); } - error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end, -1); + error = dmu_free_long_range(zsb->z_os, zp->z_id, end, -1); if (error) { zfs_range_unlock(rl); return (error); } top: - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); error = dmu_tx_assign(tx, TXG_NOWAIT); @@ -1347,44 +1198,18 @@ top: } zp->z_size = end; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, sizeof (zp->z_size)); if (end == 0) { zp->z_pflags &= ~ZFS_SPARSE; - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8); } VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0); dmu_tx_commit(tx); -#ifdef HAVE_ZPL - /* - * Clear any mapped pages in the truncated region. This has to - * happen outside of the transaction to avoid the possibility of - * a deadlock with someone trying to push a page that we are - * about to invalidate. - */ - if (vn_has_cached_data(vp)) { - page_t *pp; - uint64_t start = end & PAGEMASK; - int poff = end & PAGEOFFSET; - - if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) { - /* - * We need to zero a partial page. - */ - pagezero(pp, poff, PAGESIZE - poff); - start += PAGESIZE; - page_unlock(pp); - } - error = pvn_vplist_dirty(vp, start, zfs_no_putpage, - B_INVAL | B_TRUNC, NULL); - ASSERT(error == 0); - } -#endif /* HAVE_ZPL */ - zfs_range_unlock(rl); return (0); @@ -1399,25 +1224,25 @@ top: * flag - current file open mode flags. * log - TRUE if this action should be logged * - * RETURN: 0 if success + * RETURN: 0 if success * error code if failure */ int zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) { -#ifdef HAVE_ZPL - vnode_t *vp = ZTOV(zp); -#endif /* HAVE_ZPL */ +#ifdef HAVE_MANDLOCKS + struct inode *ip = ZTOI(zp); +#endif /* HAVE_MANDLOCKS */ dmu_tx_t *tx; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - zilog_t *zilog = zfsvfs->z_log; + zfs_sb_t *zsb = ZTOZSB(zp); + zilog_t *zilog = zsb->z_log; uint64_t mode; uint64_t mtime[2], ctime[2]; sa_bulk_attr_t bulk[3]; int count = 0; int error; - if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_MODE(zfsvfs), &mode, + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_MODE(zsb), &mode, sizeof (mode))) != 0) return (error); @@ -1429,17 +1254,17 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) return (error); } -#ifdef HAVE_ZPL +#ifdef HAVE_MANDLOCKS /* * Check for any locks in the region to be freed. */ - if (MANDLOCK(vp, (mode_t)mode)) { + if (MANDLOCK(ip, (mode_t)mode)) { uint64_t length = (len ? len : zp->z_size - off); - if (error = chklock(vp, FWRITE, off, length, flag, NULL)) + if (error = chklock(ip, FWRITE, off, length, flag, NULL)) return (error); } -#endif /* HAVE_ZPL */ +#endif /* HAVE_MANDLOCKS */ if (len == 0) { error = zfs_trunc(zp, off); @@ -1451,7 +1276,7 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) if (error || !log) return (error); log: - tx = dmu_tx_create(zfsvfs->z_os); + tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); error = dmu_tx_assign(tx, TXG_NOWAIT); @@ -1465,9 +1290,9 @@ log: return (error); } - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, mtime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, ctime, 16); - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, ctime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8); zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); @@ -1589,7 +1414,6 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) ASSERT(error == 0); dmu_buf_rele(db, FTAG); -#endif /* HAVE_ZPL */ } #endif /* _KERNEL */ From 3c4988c83e4f278cd6c8076f6cdb8e4858d05840 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 8 Feb 2011 11:29:50 -0800 Subject: [PATCH 45/75] Add zp->z_is_zvol flag A new flag is required for the zfs_rlock code to determine if it is operation of the zvol of zpl dataset. This used to be keyed off the zp->z_vnode, which was a hack to begin with, but with the removal of vnodes we needed a dedicated flag. --- include/sys/zfs_znode.h | 2 +- module/zfs/zfs_rlock.c | 4 ++-- module/zfs/zvol.c | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 2f25cc7fe..53bd18109 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -209,7 +209,7 @@ typedef struct znode { list_node_t z_link_node; /* all znodes in fs link */ sa_handle_t *z_sa_hdl; /* handle to sa data */ boolean_t z_is_sa; /* are we native sa? */ - void (*z_set_ops_inode) (struct inode *); /* set inode ops */ + boolean_t z_is_zvol; /* are we used by the zvol */ struct inode z_inode; /* generic vfs inode */ } znode_t; diff --git a/module/zfs/zfs_rlock.c b/module/zfs/zfs_rlock.c index 6709ce80b..9362fb4e8 100644 --- a/module/zfs/zfs_rlock.c +++ b/module/zfs/zfs_rlock.c @@ -112,14 +112,14 @@ zfs_range_lock_writer(znode_t *zp, rl_t *new) * Range locking is also used by zvol and uses a * dummied up znode. However, for zvol, we don't need to * append or grow blocksize, and besides we don't have - * a "sa" data or z_zfsvfs - so skip that processing. + * a "sa" data or zfs_sb_t - so skip that processing. * * Yes, this is ugly, and would be solved by not handling * grow or append in range lock code. If that was done then * we could make the range locking code generically available * to other non-zfs consumers. */ - if (zp->z_vnode) { /* caller is ZPL */ + if (!zp->z_is_zvol) { /* caller is ZPL */ /* * If in append mode pick up the current end of file. * This is done under z_range_lock to avoid races. diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index b2a08fb43..3d829a3d4 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1062,6 +1062,8 @@ zvol_alloc(dev_t dev, const char *name) mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL); avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare, sizeof (rl_t), offsetof(rl_t, r_node)); + zv->zv_znode.z_is_zvol = TRUE; + spin_lock_init(&zv->zv_lock); list_link_init(&zv->zv_next); From 633e8030b3582f3579a457a803c1382fc81f56e5 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 8 Feb 2011 11:33:08 -0800 Subject: [PATCH 46/75] Wrap with HAVE_XVATTR For the moment exactly how to handle xvattr is not clear. This change largely consists of the code to comment out the offending bits until something reasonable can be done. --- module/zfs/zfs_log.c | 52 +++++-- module/zfs/zfs_replay.c | 328 ++++++++++++++++++++++------------------ 2 files changed, 213 insertions(+), 167 deletions(-) diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c index 945b734ce..5cdbb6c8d 100644 --- a/module/zfs/zfs_log.c +++ b/module/zfs/zfs_log.c @@ -69,7 +69,11 @@ int zfs_log_create_txtype(zil_create_t type, vsecattr_t *vsecp, vattr_t *vap) { +#ifdef HAVE_XVATTR int isxvattr = (vap->va_mask & AT_XVATTR); +#else + int isxvattr = 0; +#endif /* HAVE_XVATTR */ switch (type) { case Z_FILE: if (vsecp == NULL && !isxvattr) @@ -97,6 +101,7 @@ zfs_log_create_txtype(zil_create_t type, vsecattr_t *vsecp, vattr_t *vap) return (TX_MAX_TYPE); } +#ifdef HAVE_XVATTR /* * build up the log data necessary for logging xvattr_t * First lr_attr_t is initialized. following the lr_attr_t @@ -210,6 +215,7 @@ zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start) } return (start); } +#endif /* HAVE_XVATTR */ /* * zfs_log_create() is used to handle TX_CREATE, TX_CREATE_ATTR, TX_MKDIR, @@ -238,11 +244,13 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, { itx_t *itx; lr_create_t *lr; +#ifdef HAVE_XVATTR lr_acl_create_t *lracl; + xvattr_t *xvap = (xvattr_t *)vap; +#endif /* HAVE_XVATTR */ size_t aclsize; size_t xvatsize = 0; size_t txsize; - xvattr_t *xvap = (xvattr_t *)vap; void *end; size_t lrsize; size_t namesize = strlen(name) + 1; @@ -260,8 +268,10 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t); } +#ifdef HAVE_XVATTR if (vap->va_mask & AT_XVATTR) xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize); +#endif /* HAVE_XVATTR */ if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR || (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR || @@ -292,18 +302,19 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, } else { lr->lr_gid = fuidp->z_fuid_group; } - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen, + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen, sizeof (uint64_t)); - (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), + (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), lr->lr_crtime, sizeof (uint64_t) * 2); - if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zp->z_zfsvfs), &lr->lr_rdev, + if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(zp)), &lr->lr_rdev, sizeof (lr->lr_rdev)) != 0) lr->lr_rdev = 0; /* * Fill in xvattr info if any */ +#ifdef HAVE_XVATTR if (vap->va_mask & AT_XVATTR) { zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap); end = (caddr_t)lr + lrsize + xvatsize; @@ -333,6 +344,9 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, end = zfs_log_fuid_ids(fuidp, end); end = zfs_log_fuid_domains(fuidp, end); } +#else + end = (caddr_t)lr + lrsize; +#endif /* HAVE_XVATTR */ /* * Now place file name in log record */ @@ -552,12 +566,14 @@ zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype, * zfs_log_setattr() handles TX_SETATTR transactions. */ void -zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, - znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp) +zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, znode_t *zp, + struct iattr *attr, uint_t mask_applied, zfs_fuid_info_t *fuidp) { itx_t *itx; lr_setattr_t *lr; +#ifdef HAVE_XVATTR xvattr_t *xvap = (xvattr_t *)vap; +#endif /* HAVEXVATTR */ size_t recsize = sizeof (lr_setattr_t); void *start; @@ -569,32 +585,35 @@ zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, * for lr_attr_t + xvattr mask, mapsize and create time * plus actual attribute values */ - if (vap->va_mask & AT_XVATTR) +#ifdef HAVE_XVATTR + if (attr->ia_valid & AT_XVATTR) recsize = sizeof (*lr) + ZIL_XVAT_SIZE(xvap->xva_mapsize); if (fuidp) recsize += fuidp->z_domain_str_sz; +#endif /* HAVE_XVATTR */ itx = zil_itx_create(txtype, recsize); lr = (lr_setattr_t *)&itx->itx_lr; lr->lr_foid = zp->z_id; lr->lr_mask = (uint64_t)mask_applied; - lr->lr_mode = (uint64_t)vap->va_mode; - if ((mask_applied & AT_UID) && IS_EPHEMERAL(vap->va_uid)) + lr->lr_mode = (uint64_t)attr->ia_mode; + if ((mask_applied & ATTR_UID) && IS_EPHEMERAL(attr->ia_uid)) lr->lr_uid = fuidp->z_fuid_owner; else - lr->lr_uid = (uint64_t)vap->va_uid; + lr->lr_uid = (uint64_t)attr->ia_uid; - if ((mask_applied & AT_GID) && IS_EPHEMERAL(vap->va_gid)) + if ((mask_applied & ATTR_GID) && IS_EPHEMERAL(attr->ia_gid)) lr->lr_gid = fuidp->z_fuid_group; else - lr->lr_gid = (uint64_t)vap->va_gid; + lr->lr_gid = (uint64_t)attr->ia_gid; - lr->lr_size = (uint64_t)vap->va_size; - ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime); - ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime); + lr->lr_size = (uint64_t)attr->ia_size; + ZFS_TIME_ENCODE(&attr->ia_atime, lr->lr_atime); + ZFS_TIME_ENCODE(&attr->ia_mtime, lr->lr_mtime); start = (lr_setattr_t *)(lr + 1); - if (vap->va_mask & AT_XVATTR) { +#ifdef HAVE_XVATTR + if (attr->ia_valid & ATTR_XVATTR) { zfs_log_xvattr((lr_attr_t *)start, xvap); start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize); } @@ -605,6 +624,7 @@ zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, if (fuidp) (void) zfs_log_fuid_domains(fuidp, start); +#endif /* HAVE_XVATTR */ itx->itx_sync = (zp->z_sync_cnt != 0); zil_itx_assign(zilog, itx, tx); diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index 2c258948b..f02d5add3 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -22,8 +22,6 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ -#ifdef HAVE_ZPL - #include #include #include @@ -56,26 +54,24 @@ */ static void -zfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode, - uint64_t uid, uint64_t gid, uint64_t rdev, uint64_t nodeid) +zfs_init_iattr(struct iattr *attr, uint64_t mask, uint64_t mode, + uint64_t uid, uint64_t gid) { - bzero(vap, sizeof (*vap)); - vap->va_mask = (uint_t)mask; - vap->va_type = IFTOVT(mode); - vap->va_mode = mode & MODEMASK; - vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid; - vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid; - vap->va_rdev = zfs_cmpldev(rdev); - vap->va_nodeid = nodeid; + memset(attr, 0, sizeof(*attr)); + attr->ia_valid = (uint_t)mask; + attr->ia_mode = mode; + attr->ia_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid; + attr->ia_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid; } /* ARGSUSED */ static int -zfs_replay_error(zfsvfs_t *zfsvfs, lr_t *lr, boolean_t byteswap) +zfs_replay_error(zfs_sb_t *zsb, lr_t *lr, boolean_t byteswap) { return (ENOTSUP); } +#ifdef HAVE_XVATTR static void zfs_replay_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) { @@ -136,6 +132,7 @@ zfs_replay_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) xoap->xoa_sparse = ((*attrs & XAT0_SPARSE) != 0); } +#endif /* HAVE_XVATTR */ static int zfs_replay_domain_cnt(uint64_t uid, uint64_t gid) @@ -264,16 +261,17 @@ zfs_replay_swap_attrs(lr_attr_t *lrattr) * as option FUID information. */ static int -zfs_replay_create_acl(zfsvfs_t *zfsvfs, - lr_acl_create_t *lracl, boolean_t byteswap) +zfs_replay_create_acl(zfs_sb_t *zsb, lr_acl_create_t *lracl, boolean_t byteswap) { char *name = NULL; /* location determined later */ lr_create_t *lr = (lr_create_t *)lracl; znode_t *dzp; - vnode_t *vp = NULL; + struct inode *ip = NULL; +#ifdef HAVE_XVATTR xvattr_t xva; - int vflg = 0; vsecattr_t vsec = { 0 }; +#endif /* HAVE_XVATTR */ + int vflg = 0; lr_attr_t *lrattr; void *aclstart; void *fuidstart; @@ -301,12 +299,13 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, } } - if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0) return (error); +#ifdef HAVE_XVATTR xva_init(&xva); - zfs_init_vattr(&xva.xva_vattr, AT_TYPE | AT_MODE | AT_UID | AT_GID, - lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid); + zfs_init_iattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID, + lr->lr_mode, lr->lr_uid, lr->lr_gid, /*lr->lr_rdev, lr->lr_foid*/); /* * All forms of zfs create (create, mkdir, mkxattrdir, symlink) @@ -317,8 +316,9 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, */ ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime); xva.xva_vattr.va_nblocks = lr->lr_gen; +#endif /* HAVE_XVATTR */ - error = dmu_object_info(zfsvfs->z_os, lr->lr_foid, NULL); + error = dmu_object_info(zsb->z_os, lr->lr_foid, NULL); if (error != ENOENT) goto bail; @@ -329,11 +329,12 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, aclstart = (caddr_t)(lracl + 1); fuidstart = (caddr_t)aclstart + ZIL_ACE_LENGTH(lracl->lr_acl_bytes); - zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, + zsb->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); /*FALLTHROUGH*/ case TX_CREATE_ACL_ATTR: +#ifdef HAVE_XVATTR if (name == NULL) { lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); @@ -345,27 +346,29 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, vsec.vsa_aclcnt = lracl->lr_aclcnt; vsec.vsa_aclentsz = lracl->lr_acl_bytes; vsec.vsa_aclflags = lracl->lr_acl_flags; - if (zfsvfs->z_fuid_replay == NULL) { + if (zsb->z_fuid_replay == NULL) { fuidstart = (caddr_t)(lracl + 1) + xvatlen + ZIL_ACE_LENGTH(lracl->lr_acl_bytes); - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); } - error = zfs_create(ZTOV(dzp), name, &xva.xva_vattr, - 0, 0, &vp, kcred, vflg, NULL, &vsec); + error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr, + 0, 0, &ip, kcred, vflg, NULL, &vsec); +#endif /* HAVE_XVATTR */ break; case TX_MKDIR_ACL: aclstart = (caddr_t)(lracl + 1); fuidstart = (caddr_t)aclstart + ZIL_ACE_LENGTH(lracl->lr_acl_bytes); - zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, + zsb->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); /*FALLTHROUGH*/ case TX_MKDIR_ACL_ATTR: +#ifdef HAVE_XVATTR if (name == NULL) { lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); @@ -376,47 +379,50 @@ zfs_replay_create_acl(zfsvfs_t *zfsvfs, vsec.vsa_aclcnt = lracl->lr_aclcnt; vsec.vsa_aclentsz = lracl->lr_acl_bytes; vsec.vsa_aclflags = lracl->lr_acl_flags; - if (zfsvfs->z_fuid_replay == NULL) { + if (zsb->z_fuid_replay == NULL) { fuidstart = (caddr_t)(lracl + 1) + xvatlen + ZIL_ACE_LENGTH(lracl->lr_acl_bytes); - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); } - error = zfs_mkdir(ZTOV(dzp), name, &xva.xva_vattr, - &vp, kcred, NULL, vflg, &vsec); + error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr, + &ip, kcred, NULL, vflg, &vsec); +#endif /* HAVE_XVATTR */ break; default: error = ENOTSUP; } bail: - if (error == 0 && vp != NULL) - VN_RELE(vp); + if (error == 0 && ip != NULL) + iput(ip); - VN_RELE(ZTOV(dzp)); + iput(ZTOI(dzp)); - if (zfsvfs->z_fuid_replay) - zfs_fuid_info_free(zfsvfs->z_fuid_replay); - zfsvfs->z_fuid_replay = NULL; + if (zsb->z_fuid_replay) + zfs_fuid_info_free(zsb->z_fuid_replay); + zsb->z_fuid_replay = NULL; return (error); } static int -zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) +zfs_replay_create(zfs_sb_t *zsb, lr_create_t *lr, boolean_t byteswap) { char *name = NULL; /* location determined later */ char *link; /* symlink content follows name */ znode_t *dzp; - vnode_t *vp = NULL; + struct inode *ip = NULL; xvattr_t xva; int vflg = 0; +#ifdef HAVE_XVATTR size_t lrsize = sizeof (lr_create_t); lr_attr_t *lrattr; - void *start; size_t xvatlen; +#endif /* HAVE_XVATTR */ + void *start; uint64_t txtype; int error; @@ -428,12 +434,13 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) } - if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0) return (error); +#ifdef HAVE_XVATTR xva_init(&xva); - zfs_init_vattr(&xva.xva_vattr, AT_TYPE | AT_MODE | AT_UID | AT_GID, - lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid); + zfs_init_iattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID, + lr->lr_mode, lr->lr_uid, lr->lr_gid, /*lr->lr_rdev, lr->lr_foid*/); /* * All forms of zfs create (create, mkdir, mkxattrdir, symlink) @@ -444,8 +451,9 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) */ ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime); xva.xva_vattr.va_nblocks = lr->lr_gen; +#endif /* HAVE_XVATTR */ - error = dmu_object_info(zfsvfs->z_os, lr->lr_foid, NULL); + error = dmu_object_info(zsb->z_os, lr->lr_foid, NULL); if (error != ENOENT) goto out; @@ -462,75 +470,79 @@ zfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap) (int)lr->lr_common.lrc_txtype != TX_MKDIR_ATTR && (int)lr->lr_common.lrc_txtype != TX_CREATE_ATTR) { start = (lr + 1); - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); } switch (txtype) { case TX_CREATE_ATTR: +#ifdef HAVE_XVATTR lrattr = (lr_attr_t *)(caddr_t)(lr + 1); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); start = (caddr_t)(lr + 1) + xvatlen; - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); name = (char *)start; +#endif /* HAVE_XVATTR */ /*FALLTHROUGH*/ case TX_CREATE: if (name == NULL) name = (char *)start; - error = zfs_create(ZTOV(dzp), name, &xva.xva_vattr, - 0, 0, &vp, kcred, vflg, NULL, NULL); + error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr, + 0, 0, &ip, kcred, vflg, NULL); break; case TX_MKDIR_ATTR: +#ifdef HAVE_XVATTR lrattr = (lr_attr_t *)(caddr_t)(lr + 1); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); start = (caddr_t)(lr + 1) + xvatlen; - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); name = (char *)start; +#endif /* HAVE_XVATTR */ /*FALLTHROUGH*/ case TX_MKDIR: if (name == NULL) name = (char *)(lr + 1); - error = zfs_mkdir(ZTOV(dzp), name, &xva.xva_vattr, - &vp, kcred, NULL, vflg, NULL); + error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr, + &ip, kcred, vflg, NULL); break; case TX_MKXATTR: - error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &vp, kcred); + error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &ip, kcred); break; case TX_SYMLINK: name = (char *)(lr + 1); link = name + strlen(name) + 1; - error = zfs_symlink(ZTOV(dzp), name, &xva.xva_vattr, - link, kcred, NULL, vflg); + error = zfs_symlink(ZTOI(dzp), name, &xva.xva_vattr, + link, &ip, kcred, vflg); break; default: error = ENOTSUP; } out: - if (error == 0 && vp != NULL) - VN_RELE(vp); + if (error == 0 && ip != NULL) + iput(ip); - VN_RELE(ZTOV(dzp)); + iput(ZTOI(dzp)); - if (zfsvfs->z_fuid_replay) - zfs_fuid_info_free(zfsvfs->z_fuid_replay); - zfsvfs->z_fuid_replay = NULL; + if (zsb->z_fuid_replay) + zfs_fuid_info_free(zsb->z_fuid_replay); + zsb->z_fuid_replay = NULL; return (error); } static int -zfs_replay_remove(zfsvfs_t *zfsvfs, lr_remove_t *lr, boolean_t byteswap) +zfs_replay_remove(zfs_sb_t *zsb, lr_remove_t *lr, boolean_t byteswap) { char *name = (char *)(lr + 1); /* name follows lr_remove_t */ znode_t *dzp; @@ -540,60 +552,63 @@ zfs_replay_remove(zfsvfs_t *zfsvfs, lr_remove_t *lr, boolean_t byteswap) if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0) return (error); +#ifdef HAVE_PN_UTILS if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; +#endif switch ((int)lr->lr_common.lrc_txtype) { case TX_REMOVE: - error = zfs_remove(ZTOV(dzp), name, kcred, NULL, vflg); + error = zfs_remove(ZTOI(dzp), name, kcred); break; case TX_RMDIR: - error = zfs_rmdir(ZTOV(dzp), name, NULL, kcred, NULL, vflg); + error = zfs_rmdir(ZTOI(dzp), name, NULL, kcred, vflg); break; default: error = ENOTSUP; } - VN_RELE(ZTOV(dzp)); + iput(ZTOI(dzp)); return (error); } static int -zfs_replay_link(zfsvfs_t *zfsvfs, lr_link_t *lr, boolean_t byteswap) +zfs_replay_link(zfs_sb_t *zsb, lr_link_t *lr, boolean_t byteswap) { char *name = (char *)(lr + 1); /* name follows lr_link_t */ znode_t *dzp, *zp; int error; - int vflg = 0; if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0) return (error); - if ((error = zfs_zget(zfsvfs, lr->lr_link_obj, &zp)) != 0) { - VN_RELE(ZTOV(dzp)); + if ((error = zfs_zget(zsb, lr->lr_link_obj, &zp)) != 0) { + iput(ZTOI(dzp)); return (error); } +#ifdef HAVE_PN_UTILS if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; +#endif - error = zfs_link(ZTOV(dzp), ZTOV(zp), name, kcred, NULL, vflg); + error = zfs_link(ZTOI(dzp), ZTOI(zp), name, kcred); - VN_RELE(ZTOV(zp)); - VN_RELE(ZTOV(dzp)); + iput(ZTOI(zp)); + iput(ZTOI(dzp)); return (error); } static int -zfs_replay_rename(zfsvfs_t *zfsvfs, lr_rename_t *lr, boolean_t byteswap) +zfs_replay_rename(zfs_sb_t *zsb, lr_rename_t *lr, boolean_t byteswap) { char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */ char *tname = sname + strlen(sname) + 1; @@ -604,39 +619,39 @@ zfs_replay_rename(zfsvfs_t *zfsvfs, lr_rename_t *lr, boolean_t byteswap) if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_sdoid, &sdzp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_sdoid, &sdzp)) != 0) return (error); - if ((error = zfs_zget(zfsvfs, lr->lr_tdoid, &tdzp)) != 0) { - VN_RELE(ZTOV(sdzp)); + if ((error = zfs_zget(zsb, lr->lr_tdoid, &tdzp)) != 0) { + iput(ZTOI(sdzp)); return (error); } if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; - error = zfs_rename(ZTOV(sdzp), sname, ZTOV(tdzp), tname, kcred, - NULL, vflg); + error = zfs_rename(ZTOI(sdzp), sname, ZTOI(tdzp), tname, kcred, vflg); - VN_RELE(ZTOV(tdzp)); - VN_RELE(ZTOV(sdzp)); + iput(ZTOI(tdzp)); + iput(ZTOI(sdzp)); return (error); } static int -zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) +zfs_replay_write(zfs_sb_t *zsb, lr_write_t *lr, boolean_t byteswap) { +#if 0 char *data = (char *)(lr + 1); /* data follows lr_write_t */ +#endif znode_t *zp; int error; - ssize_t resid; uint64_t eod, offset, length; if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) { + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) { /* * As we can log writes out of order, it's possible the * file has been removed. In this case just drop the write @@ -659,10 +674,10 @@ zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) * write needs to be there. So we write the whole block and * reduce the eof. This needs to be done within the single dmu * transaction created within vn_rdwr -> zfs_write. So a possible - * new end of file is passed through in zfsvfs->z_replay_eof + * new end of file is passed through in zsb->z_replay_eof */ - zfsvfs->z_replay_eof = 0; /* 0 means don't change end of file */ + zsb->z_replay_eof = 0; /* 0 means don't change end of file */ /* If it's a dmu_sync() block, write the whole block */ if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) { @@ -672,14 +687,19 @@ zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) length = blocksize; } if (zp->z_size < eod) - zfsvfs->z_replay_eof = eod; + zsb->z_replay_eof = eod; } - error = vn_rdwr(UIO_WRITE, ZTOV(zp), data, length, offset, + /* + * XXX: Use zfs_write() once uio types are removed + */ +#if 0 + error = vn_rdwr(UIO_WRITE, ZTOI(zp), data, length, offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid); +#endif - VN_RELE(ZTOV(zp)); - zfsvfs->z_replay_eof = 0; /* safety */ + iput(ZTOI(zp)); + zsb->z_replay_eof = 0; /* safety */ return (error); } @@ -691,7 +711,7 @@ zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) * the file is grown. */ static int -zfs_replay_write2(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) +zfs_replay_write2(zfs_sb_t *zsb, lr_write_t *lr, boolean_t byteswap) { znode_t *zp; int error; @@ -700,19 +720,19 @@ zfs_replay_write2(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap) if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) return (error); top: end = lr->lr_offset + lr->lr_length; if (end > zp->z_size) { - dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os); + dmu_tx_t *tx = dmu_tx_create(zsb->z_os); zp->z_size = end; dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); if (error == ERESTART) { dmu_tx_wait(tx); dmu_tx_abort(tx); @@ -721,22 +741,22 @@ top: dmu_tx_abort(tx); return (error); } - (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zfsvfs), + (void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb), (void *)&zp->z_size, sizeof (uint64_t), tx); /* Ensure the replayed seq is updated */ - (void) zil_replaying(zfsvfs->z_log, tx); + (void) zil_replaying(zsb->z_log, tx); dmu_tx_commit(tx); } - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); return (error); } static int -zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) +zfs_replay_truncate(zfs_sb_t *zsb, lr_truncate_t *lr, boolean_t byteswap) { znode_t *zp; flock64_t fl; @@ -745,7 +765,7 @@ zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) return (error); bzero(&fl, sizeof (fl)); @@ -754,68 +774,75 @@ zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) fl.l_start = lr->lr_offset; fl.l_len = lr->lr_length; - error = zfs_space(ZTOV(zp), F_FREESP, &fl, FWRITE | FOFFMAX, - lr->lr_offset, kcred, NULL); + error = zfs_space(ZTOI(zp), F_FREESP, &fl, FWRITE | FOFFMAX, + lr->lr_offset, kcred); - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); return (error); } static int -zfs_replay_setattr(zfsvfs_t *zfsvfs, lr_setattr_t *lr, boolean_t byteswap) +zfs_replay_setattr(zfs_sb_t *zsb, lr_setattr_t *lr, boolean_t byteswap) { znode_t *zp; +#ifdef HAVE_XVATTR xvattr_t xva; - vattr_t *vap = &xva.xva_vattr; +#endif /* HAVE_XATTR */ + struct iattr attr; int error; void *start; +#ifdef HAVE_XVATTR xva_init(&xva); +#endif /* HAVE_XVATTR */ if (byteswap) { byteswap_uint64_array(lr, sizeof (*lr)); +#ifdef HAVE_XVATTR if ((lr->lr_mask & AT_XVATTR) && - zfsvfs->z_version >= ZPL_VERSION_INITIAL) + zsb->z_version >= ZPL_VERSION_INITIAL) zfs_replay_swap_attrs((lr_attr_t *)(lr + 1)); +#endif /* HAVE_XVATTR */ } - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) return (error); - zfs_init_vattr(vap, lr->lr_mask, lr->lr_mode, - lr->lr_uid, lr->lr_gid, 0, lr->lr_foid); + zfs_init_iattr(&attr, lr->lr_mask, lr->lr_mode, lr->lr_uid, lr->lr_gid); - vap->va_size = lr->lr_size; - ZFS_TIME_DECODE(&vap->va_atime, lr->lr_atime); - ZFS_TIME_DECODE(&vap->va_mtime, lr->lr_mtime); + attr.ia_size = lr->lr_size; + ZFS_TIME_DECODE(&attr.ia_atime, lr->lr_atime); + ZFS_TIME_DECODE(&attr.ia_mtime, lr->lr_mtime); /* * Fill in xvattr_t portions if necessary. */ start = (lr_setattr_t *)(lr + 1); - if (vap->va_mask & AT_XVATTR) { +#ifdef HAVE_XVATTR + if (iattr->ia_mask & AT_XVATTR) { zfs_replay_xvattr((lr_attr_t *)start, &xva); start = (caddr_t)start + ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize); } else xva.xva_vattr.va_mask &= ~AT_XVATTR; +#endif /* HAVE_XVATTR */ - zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start, + zsb->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); - error = zfs_setattr(ZTOV(zp), vap, 0, kcred, NULL); + error = zfs_setattr(ZTOI(zp), &attr, 0, kcred); - zfs_fuid_info_free(zfsvfs->z_fuid_replay); - zfsvfs->z_fuid_replay = NULL; - VN_RELE(ZTOV(zp)); + zfs_fuid_info_free(zsb->z_fuid_replay); + zsb->z_fuid_replay = NULL; + iput(ZTOI(zp)); return (error); } static int -zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) +zfs_replay_acl_v0(zfs_sb_t *zsb, lr_acl_v0_t *lr, boolean_t byteswap) { ace_t *ace = (ace_t *)(lr + 1); /* ace array follows lr_acl_t */ vsecattr_t vsa; @@ -827,7 +854,7 @@ zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) zfs_oldace_byteswap(ace, lr->lr_aclcnt); } - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) return (error); bzero(&vsa, sizeof (vsa)); @@ -837,9 +864,9 @@ zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) vsa.vsa_aclflags = 0; vsa.vsa_aclentp = ace; - error = zfs_setsecattr(ZTOV(zp), &vsa, 0, kcred, NULL); + error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred); - VN_RELE(ZTOV(zp)); + iput(ZTOI(zp)); return (error); } @@ -859,7 +886,7 @@ zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) * */ static int -zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap) +zfs_replay_acl(zfs_sb_t *zsb, lr_acl_t *lr, boolean_t byteswap) { ace_t *ace = (ace_t *)(lr + 1); vsecattr_t vsa; @@ -876,7 +903,7 @@ zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap) } } - if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) + if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) return (error); bzero(&vsa, sizeof (vsa)); @@ -890,18 +917,18 @@ zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap) void *fuidstart = (caddr_t)ace + ZIL_ACE_LENGTH(lr->lr_acl_bytes); - zfsvfs->z_fuid_replay = + zsb->z_fuid_replay = zfs_replay_fuids(fuidstart, &fuidstart, lr->lr_fuidcnt, lr->lr_domcnt, 0, 0); } - error = zfs_setsecattr(ZTOV(zp), &vsa, 0, kcred, NULL); + error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred); - if (zfsvfs->z_fuid_replay) - zfs_fuid_info_free(zfsvfs->z_fuid_replay); + if (zsb->z_fuid_replay) + zfs_fuid_info_free(zsb->z_fuid_replay); - zfsvfs->z_fuid_replay = NULL; - VN_RELE(ZTOV(zp)); + zsb->z_fuid_replay = NULL; + iput(ZTOI(zp)); return (error); } @@ -910,26 +937,25 @@ zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap) * Callback vectors for replaying records */ zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE] = { - zfs_replay_error, /* 0 no such transaction type */ - zfs_replay_create, /* TX_CREATE */ - zfs_replay_create, /* TX_MKDIR */ - zfs_replay_create, /* TX_MKXATTR */ - zfs_replay_create, /* TX_SYMLINK */ - zfs_replay_remove, /* TX_REMOVE */ - zfs_replay_remove, /* TX_RMDIR */ - zfs_replay_link, /* TX_LINK */ - zfs_replay_rename, /* TX_RENAME */ - zfs_replay_write, /* TX_WRITE */ - zfs_replay_truncate, /* TX_TRUNCATE */ - zfs_replay_setattr, /* TX_SETATTR */ - zfs_replay_acl_v0, /* TX_ACL_V0 */ - zfs_replay_acl, /* TX_ACL */ - zfs_replay_create_acl, /* TX_CREATE_ACL */ - zfs_replay_create, /* TX_CREATE_ATTR */ - zfs_replay_create_acl, /* TX_CREATE_ACL_ATTR */ - zfs_replay_create_acl, /* TX_MKDIR_ACL */ - zfs_replay_create, /* TX_MKDIR_ATTR */ - zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */ - zfs_replay_write2, /* TX_WRITE2 */ + (zil_replay_func_t *)zfs_replay_error, /* no such type */ + (zil_replay_func_t *)zfs_replay_create, /* TX_CREATE */ + (zil_replay_func_t *)zfs_replay_create, /* TX_MKDIR */ + (zil_replay_func_t *)zfs_replay_create, /* TX_MKXATTR */ + (zil_replay_func_t *)zfs_replay_create, /* TX_SYMLINK */ + (zil_replay_func_t *)zfs_replay_remove, /* TX_REMOVE */ + (zil_replay_func_t *)zfs_replay_remove, /* TX_RMDIR */ + (zil_replay_func_t *)zfs_replay_link, /* TX_LINK */ + (zil_replay_func_t *)zfs_replay_rename, /* TX_RENAME */ + (zil_replay_func_t *)zfs_replay_write, /* TX_WRITE */ + (zil_replay_func_t *)zfs_replay_truncate, /* TX_TRUNCATE */ + (zil_replay_func_t *)zfs_replay_setattr, /* TX_SETATTR */ + (zil_replay_func_t *)zfs_replay_acl_v0, /* TX_ACL_V0 */ + (zil_replay_func_t *)zfs_replay_acl, /* TX_ACL */ + (zil_replay_func_t *)zfs_replay_create_acl, /* TX_CREATE_ACL */ + (zil_replay_func_t *)zfs_replay_create, /* TX_CREATE_ATTR */ + (zil_replay_func_t *)zfs_replay_create_acl, /* TX_CREATE_ACL_ATTR */ + (zil_replay_func_t *)zfs_replay_create_acl, /* TX_MKDIR_ACL */ + (zil_replay_func_t *)zfs_replay_create, /* TX_MKDIR_ATTR */ + (zil_replay_func_t *)zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */ + (zil_replay_func_t *)zfs_replay_write2, /* TX_WRITE2 */ }; -#endif /* HAVE_ZPL */ From 1efb473f8919c5f195e127136b79c6d3b1eb1c81 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:03:58 -0800 Subject: [PATCH 47/75] Add Hooks for Linux File Operations The Linux specific file operations have all been located in the file zpl_file.c. These functions primarily rely on the reworked zfs_* functions to do their job. They are also responsible for converting the possible Solaris style error codes to negative Linux errors. This first zpl_* commit also includes a common zpl.h header with minimal entries to register the Linux specific hooks. In also adds all the new zpl_* file to the Makefile.in. This is not a standalone commit, you required the following zpl_* commits. --- include/sys/Makefile.am | 1 + include/sys/Makefile.in | 2 + include/sys/zpl.h | 63 ++++++++++++++ lib/libzpool/Makefile.am | 4 + lib/libzpool/Makefile.in | 4 + module/zfs/Makefile.in | 4 + module/zfs/zpl_file.c | 173 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 251 insertions(+) create mode 100644 include/sys/zpl.h create mode 100644 module/zfs/zpl_file.c diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 63dc24e5b..bde71b75e 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -75,6 +75,7 @@ KERNEL_H = \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h USER_H = diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 9243f75ab..1525d1d07 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -163,6 +163,7 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -531,6 +532,7 @@ KERNEL_H = \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h USER_H = diff --git a/include/sys/zpl.h b/include/sys/zpl.h new file mode 100644 index 000000000..33f4f621f --- /dev/null +++ b/include/sys/zpl.h @@ -0,0 +1,63 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + +#ifndef _SYS_ZPL_H +#define _SYS_ZPL_H + +#include + +/* zpl_inode.c */ +extern const struct inode_operations zpl_inode_operations; +extern const struct inode_operations zpl_dir_inode_operations; +extern const struct inode_operations zpl_symlink_inode_operations; +extern const struct inode_operations zpl_special_inode_operations; + +/* zpl_file.c */ +extern ssize_t zpl_read_common(struct inode *ip, const char *buf, + size_t len, loff_t pos, uio_seg_t segment, int flags, cred_t *cr); +extern ssize_t zpl_write_common(struct inode *ip, const char *buf, + size_t len, loff_t pos, uio_seg_t segment, int flags, cred_t *cr); + +extern const struct address_space_operations zpl_address_space_operations; +extern const struct file_operations zpl_file_operations; +extern const struct file_operations zpl_dir_file_operations; + +/* zpl_super.c */ +typedef struct zpl_mount_data { + const char *z_osname; /* Dataset name */ + void *z_data; /* Mount options string */ + struct vfsmount *z_vfs; /* VFS mount point */ +} zpl_mount_data_t; + +extern const struct super_operations zpl_super_operations; +/* extern const struct export_operations zpl_export_operations; */ +extern struct file_system_type zpl_fs_type; + +/* zpl_xattr.c */ +extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size); +extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip); + +extern struct xattr_handler *zpl_xattr_handlers[]; + +#endif /* _SYS_ZPL_H */ diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 450f4cca1..b15830ded 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -106,5 +106,9 @@ EXTRA_DIST = \ $(top_srcdir)/module/zfs/zfs_rlock.c \ $(top_srcdir)/module/zfs/zfs_vfsops.c \ $(top_srcdir)/module/zfs/zfs_vnops.c \ + $(top_srcdir)/module/zfs/zpl_file.c \ + $(top_srcdir)/module/zfs/zpl_inode.c \ + $(top_srcdir)/module/zfs/zpl_super.c \ + $(top_srcdir)/module/zfs/zpl_xattr.c \ $(top_srcdir)/module/zfs/zvol.c \ $(top_srcdir)/module/zpios/pios.c diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 29d312f9d..344612d31 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -427,6 +427,10 @@ EXTRA_DIST = \ $(top_srcdir)/module/zfs/zfs_rlock.c \ $(top_srcdir)/module/zfs/zfs_vfsops.c \ $(top_srcdir)/module/zfs/zfs_vnops.c \ + $(top_srcdir)/module/zfs/zpl_file.c \ + $(top_srcdir)/module/zfs/zpl_inode.c \ + $(top_srcdir)/module/zfs/zpl_super.c \ + $(top_srcdir)/module/zfs/zpl_xattr.c \ $(top_srcdir)/module/zfs/zvol.c \ $(top_srcdir)/module/zpios/pios.c diff --git a/module/zfs/Makefile.in b/module/zfs/Makefile.in index 7d42481d1..5a99852a1 100644 --- a/module/zfs/Makefile.in +++ b/module/zfs/Makefile.in @@ -83,5 +83,9 @@ $(MODULE)-objs += @top_srcdir@/module/zfs/zio_checksum.o $(MODULE)-objs += @top_srcdir@/module/zfs/zio_compress.o $(MODULE)-objs += @top_srcdir@/module/zfs/zio_inject.o $(MODULE)-objs += @top_srcdir@/module/zfs/zle.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_file.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_inode.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_super.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_xattr.o $(MODULE)-objs += @top_srcdir@/module/zfs/zrlock.o $(MODULE)-objs += @top_srcdir@/module/zfs/zvol.o diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c new file mode 100644 index 000000000..41901bb6c --- /dev/null +++ b/module/zfs/zpl_file.c @@ -0,0 +1,173 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + + +#include +#include +#include +#include + + +static int +zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct dentry *dentry = filp->f_path.dentry; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_readdir(dentry->d_inode, dirent, filldir, + &filp->f_pos, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_fsync(struct file *filp, struct dentry *dentry, int datasync) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_fsync(filp->f_path.dentry->d_inode, datasync, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +ssize_t +zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t pos, + uio_seg_t segment, int flags, cred_t *cr) +{ + int error; + struct iovec iov; + uio_t uio; + + iov.iov_base = (void *)buf; + iov.iov_len = len; + + uio.uio_iov = &iov; + uio.uio_resid = len; + uio.uio_iovcnt = 1; + uio.uio_loffset = pos; + uio.uio_limit = MAXOFFSET_T; + uio.uio_segflg = segment; + + error = -zfs_read(ip, &uio, flags, cr); + if (error < 0) + return (error); + + return (len - uio.uio_resid); +} + +static ssize_t +zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) +{ + cred_t *cr; + ssize_t read; + + cr = (cred_t *)get_current_cred(); + read = zpl_read_common(filp->f_mapping->host, buf, len, *ppos, + UIO_USERSPACE, filp->f_flags, cr); + put_cred(cr); + + if (read < 0) + return (read); + + *ppos += read; + return (read); +} + +ssize_t +zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t pos, + uio_seg_t segment, int flags, cred_t *cr) +{ + int error; + struct iovec iov; + uio_t uio; + + iov.iov_base = (void *)buf; + iov.iov_len = len; + + uio.uio_iov = &iov; + uio.uio_resid = len, + uio.uio_iovcnt = 1; + uio.uio_loffset = pos; + uio.uio_limit = MAXOFFSET_T; + uio.uio_segflg = segment; + + error = -zfs_write(ip, &uio, flags, cr); + if (error < 0) + return (error); + + return (len - uio.uio_resid); +} + +static ssize_t +zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) +{ + cred_t *cr; + ssize_t wrote; + + cr = (cred_t *)get_current_cred(); + wrote = zpl_write_common(filp->f_mapping->host, buf, len, *ppos, + UIO_USERSPACE, filp->f_flags, cr); + put_cred(cr); + + if (wrote < 0) + return (wrote); + + *ppos += wrote; + return (wrote); +} + +const struct address_space_operations zpl_address_space_operations = { +#if 0 + .readpage = zpl_readpage, + .writepage = zpl_writepage, + .direct_IO = zpl_direct_IO, +#endif +}; + +const struct file_operations zpl_file_operations = { + .open = generic_file_open, + .llseek = generic_file_llseek, + .read = zpl_read, /* do_sync_read */ + .write = zpl_write, /* do_sync_write */ + .readdir = zpl_readdir, + .mmap = generic_file_mmap, + .fsync = zpl_fsync, + .aio_read = NULL, /* generic_file_aio_read */ + .aio_write = NULL, /* generic_file_aio_write */ +}; + +const struct file_operations zpl_dir_file_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .readdir = zpl_readdir, + .fsync = zpl_fsync, +}; From ee154f01bf0bdb5e85524c518c19964272d33cd9 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:08:24 -0800 Subject: [PATCH 48/75] Add Hooks for Linux Inode Operations The Linux specific inode operations have all been located in the file zpl_inode.c. These functions primarily rely on the reworked zfs_* functions to do their job. They are also responsible for converting the possible Solaris style error codes to negative Linux errors. --- module/zfs/zpl_inode.c | 331 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 module/zfs/zpl_inode.c diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c new file mode 100644 index 000000000..e866dcd4d --- /dev/null +++ b/module/zfs/zpl_inode.c @@ -0,0 +1,331 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + + +#include +#include +#include +#include + + +static struct dentry * +zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) +{ + struct inode *ip; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, NULL); + ASSERT3S(error, <=, 0); + put_cred(cr); + + if (error) { + if (error == -ENOENT) + return d_splice_alias(NULL, dentry); + else + return ERR_PTR(error); + } + + return d_splice_alias(ip, dentry); +} + +static int +zpl_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + const struct cred *cred; + struct inode *ip; + vattr_t *vap; + int error; + + cred = get_current_cred(); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mode = mode; + vap->va_mask = ATTR_MODE; + vap->va_uid = current_fsuid(); + vap->va_gid = current_fsgid(); + + error = -zfs_create(dir, (char *)dentry->d_name.name, + vap, 0, mode, &ip, (struct cred *)cred, 0, NULL); + if (error) + goto out; + + d_instantiate(dentry, ip); +out: + kmem_free(vap, sizeof(vattr_t)); + put_cred(cred); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) +{ + const struct cred *cred; + struct inode *ip; + vattr_t *vap; + int error; + + cred = get_current_cred(); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mode = mode; + vap->va_mask = ATTR_MODE; + vap->va_rdev = rdev; + vap->va_uid = current_fsuid(); + vap->va_gid = current_fsgid(); + + error = -zfs_create(dir, (char *)dentry->d_name.name, + vap, 0, mode, &ip, (struct cred *)cred, 0, NULL); + if (error) + goto out; + + d_instantiate(dentry, ip); +out: + kmem_free(vap, sizeof(vattr_t)); + put_cred(cred); + ASSERT3S(error, <=, 0); + + return (-error); +} + +static int +zpl_unlink(struct inode *dir, struct dentry *dentry) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_remove(dir, dname(dentry), cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + cred_t *cr; + vattr_t *vap; + struct inode *ip; + int error; + + cr = (cred_t *)get_current_cred(); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mode = S_IFDIR | mode; + vap->va_mask = ATTR_MODE; + vap->va_uid = current_fsuid(); + vap->va_gid = current_fsgid(); + + error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL); + if (error) + goto out; + + d_instantiate(dentry, ip); +out: + kmem_free(vap, sizeof(vattr_t)); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_rmdir(struct inode * dir, struct dentry *dentry) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_getattr(dentry->d_inode, stat, 0, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_setattr(struct dentry *dentry, struct iattr *attr) +{ + cred_t *cr; + int error; + + error = inode_change_ok(dentry->d_inode, attr); + if (error) + return (error); + + cr = (cred_t *)get_current_cred(); + error = -zfs_setattr(dentry->d_inode, attr, 0, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (-error); +} + +static int +zpl_rename(struct inode *sdip, struct dentry *sdentry, + struct inode *tdip, struct dentry *tdentry) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name) +{ + cred_t *cr; + vattr_t *vap; + struct inode *ip; + int error; + + cr = (cred_t *)get_current_cred(); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mode = S_IFLNK | S_IRWXUGO; + vap->va_mask = ATTR_MODE; + vap->va_uid = current_fsuid(); + vap->va_gid = current_fsgid(); + + error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0); + if (error) + goto out; + + d_instantiate(dentry, ip); +out: + kmem_free(vap, sizeof(vattr_t)); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static void * +zpl_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + (void) zfs_follow_link(dentry, nd); + return NULL; +} + +static void +zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) +{ + char *link; + + link = nd_get_link(nd); + if (!IS_ERR(link)) + kmem_free(link, MAXPATHLEN + 1); +} + +static int +zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) +{ + struct inode *ip = old_dentry->d_inode; + cred_t *cr; + int error; + + if (ip->i_nlink >= ZFS_LINK_MAX) + return -EMLINK; + + cr = (cred_t *)get_current_cred(); + ip->i_ctime = CURRENT_TIME_SEC; + igrab(ip); /* Use ihold() if available */ + + error = -zfs_link(dir, ip, dname(dentry), cr); + if (error) { + iput(ip); + goto out; + } + + d_instantiate(dentry, ip); +out: + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +const struct inode_operations zpl_inode_operations = { + .check_acl = NULL, + .create = zpl_create, + .link = zpl_link, + .unlink = zpl_unlink, + .symlink = zpl_symlink, + .mkdir = zpl_mkdir, + .rmdir = zpl_rmdir, + .mknod = zpl_mknod, + .rename = zpl_rename, + .setattr = zpl_setattr, + .getattr = zpl_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = zpl_xattr_list, +}; + +const struct inode_operations zpl_dir_inode_operations = { + .check_acl = NULL, + .create = zpl_create, + .lookup = zpl_lookup, + .link = zpl_link, + .unlink = zpl_unlink, + .symlink = zpl_symlink, + .mkdir = zpl_mkdir, + .rmdir = zpl_rmdir, + .mknod = zpl_mknod, + .rename = zpl_rename, + .setattr = zpl_setattr, +}; + +const struct inode_operations zpl_symlink_inode_operations = { + .check_acl = NULL, + .readlink = generic_readlink, + .follow_link = zpl_follow_link, + .put_link = zpl_put_link, +}; + +const struct inode_operations zpl_special_inode_operations = { + .check_acl = NULL, +}; From 51f0bbe425f7313a19ee54ccd3d67ed8ba686567 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:09:10 -0800 Subject: [PATCH 49/75] Add Hooks for Linux Super Block Operations The Linux specific super block operations have all been located in the file zpl_super.c. These functions primarily rely on the reworked zfs_* functions to do their job. They are also responsible for converting the possible Solaris style error codes to negative Linux errors. --- module/zfs/zpl_super.c | 168 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 module/zfs/zpl_super.c diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c new file mode 100644 index 000000000..bbb7beaf3 --- /dev/null +++ b/module/zfs/zpl_super.c @@ -0,0 +1,168 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + + +#include +#include +#include +#include + + +static struct inode * +zpl_inode_alloc(struct super_block *sb) +{ + struct inode *ip; + + VERIFY3S(zfs_inode_alloc(sb, &ip), ==, 0); + ip->i_version = 1; + + return (ip); +} + +static void +zpl_inode_destroy(struct inode *ip) +{ + ASSERT(atomic_read(&ip->i_count) == 0); + zfs_inode_destroy(ip); +} + +static void +zpl_inode_delete(struct inode *ip) +{ + loff_t oldsize = i_size_read(ip); + + i_size_write(ip, 0); + truncate_pagecache(ip, oldsize, 0); + clear_inode(ip); +} + +static void +zpl_evict_inode(struct inode *ip) +{ + zfs_inactive(ip); +} + +static void +zpl_put_super(struct super_block *sb) +{ + int error; + + error = -zfs_umount(sb); + ASSERT3S(error, <=, 0); +} + +static int +zpl_statfs(struct dentry *dentry, struct kstatfs *statp) +{ + int error; + + error = -zfs_statvfs(dentry, statp); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp) +{ + struct super_block *sb = vfsp->mnt_sb; + zfs_sb_t *zsb = sb->s_fs_info; + + /* + * The Linux VFS automatically handles the following flags: + * MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, MNT_NOATIME, MNT_READONLY + */ + + if (zsb->z_flags & ZSB_XATTR_USER) + seq_printf(seq, ",%s", "xattr"); + + return (0); +} + +static int +zpl_fill_super(struct super_block *sb, void *data, int silent) +{ + int error; + + error = -zfs_domount(sb, data, silent); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_get_sb(struct file_system_type *fs_type, int flags, + const char *osname, void *data, struct vfsmount *mnt) +{ + zpl_mount_data_t zmd = { osname, data, mnt }; + + return get_sb_nodev(fs_type, flags, &zmd, zpl_fill_super, mnt); +} + +static void +zpl_kill_sb(struct super_block *sb) +{ +#ifdef HAVE_SNAPSHOT + zfs_sb_t *zsb = sb->s_fs_info; + + if (zsb && dmu_objset_is_snapshot(zsb->z_os)) + zfs_snap_destroy(zsb); +#endif /* HAVE_SNAPSHOT */ + + kill_anon_super(sb); +} + +const struct super_operations zpl_super_operations = { + .alloc_inode = zpl_inode_alloc, + .destroy_inode = zpl_inode_destroy, + .delete_inode = zpl_inode_delete, + .dirty_inode = NULL, + .write_inode = NULL, + .drop_inode = NULL, + .clear_inode = zpl_evict_inode, + .put_super = zpl_put_super, + .write_super = NULL, + .sync_fs = NULL, + .freeze_fs = NULL, + .unfreeze_fs = NULL, + .statfs = zpl_statfs, + .remount_fs = NULL, + .show_options = zpl_show_options, + .show_stats = NULL, +}; + +#if 0 +const struct export_operations zpl_export_operations = { + .fh_to_dentry = NULL, + .fh_to_parent = NULL, + .get_parent = NULL, +}; +#endif + +struct file_system_type zpl_fs_type = { + .owner = THIS_MODULE, + .name = ZFS_DRIVER, + .get_sb = zpl_get_sb, + .kill_sb = zpl_kill_sb, +}; From cc5f931cfd623c50f283fa5cf1bc21cfd7e5c703 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 26 Jan 2011 12:10:01 -0800 Subject: [PATCH 50/75] Add Hooks for Linux Xattr Operations The Linux specific xattr operations have all been located in the file zpl_xattr.c. These functions primarily rely on the reworked zfs_* functions to do their job. They are also responsible for converting the possible Solaris style error codes to negative Linux errors. --- module/zfs/zpl_xattr.c | 432 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 module/zfs/zpl_xattr.c diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c new file mode 100644 index 000000000..910500a72 --- /dev/null +++ b/module/zfs/zpl_xattr.c @@ -0,0 +1,432 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + * + * Extended attributes (xattr) on Solaris are implemented as files + * which exist in a hidden xattr directory. These extended attributes + * can be accessed using the attropen() system call which opens + * the extended attribute. It can then be manipulated just like + * a standard file descriptor. This has a couple advantages such + * as practically no size limit on the file, and the extended + * attributes permissions may differ from those of the parent file. + * This interface is really quite clever, but it's also completely + * different than what is supported on Linux. + * + * Under Linux extended attributes are manipulated by the system + * calls getxattr(2), setxattr(2), and listxattr(2). They consider + * extended attributes to be name/value pairs where the name is a + * NULL terminated string. The name must also include one of the + * following name space prefixes: + * + * user - No restrictions and is available to user applications. + * trusted - Restricted to kernel and root (CAP_SYS_ADMIN) use. + * system - Used for access control lists (system.nfs4_acl, etc). + * security - Used by SELinux to store a files security context. + * + * This Linux interface is implemented internally using the more + * flexible Solaris style extended attributes. Every extended + * attribute is store as a file in a hidden directory associated + * with the parent file. This ensures on disk compatibility with + * zfs implementations on other platforms (Solaris, FreeBSD, MacOS). + * + * One consequence of this implementation is that when an extended + * attribute is manipulated an inode is created. This inode will + * exist in the Linux inode cache but there will be no associated + * entry in the dentry cache which references it. This is safe + * but it may result in some confusion. + * + * Longer term I would like to see the 'security.selinux' extended + * attribute moved to a SA. This should significantly improve + * performance on a SELinux enabled system by minimizing the + * number of seeks required to access a file. However, for now + * this xattr is still stored in a file because I'm pretty sure + * adding a new SA will break on-disk compatibility. + */ + + +#include +#include +#include +#include +#include + +typedef struct xattr_filldir { + size_t size; + size_t offset; + char *buf; + struct inode *inode; +} xattr_filldir_t; + +static int +zpl_xattr_filldir(void *arg, const char *name, int name_len, + loff_t offset, uint64_t objnum, unsigned int d_type) +{ + xattr_filldir_t *xf = arg; + + if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) + if (!(ITOZSB(xf->inode)->z_flags & ZSB_XATTR_USER)) + return (0); + + if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) + if (!capable(CAP_SYS_ADMIN)) + return (0); + + /* When xf->buf is NULL only calculate the required size. */ + if (xf->buf) { + if (xf->offset + name_len + 1 > xf->size) + return (-ERANGE); + + memcpy(xf->buf + xf->offset, name, name_len); + xf->buf[xf->offset + name_len] = '\0'; + } + + xf->offset += (name_len + 1); + + return (0); +} + +ssize_t +zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) +{ + struct inode *ip = dentry->d_inode; + struct inode *dxip = NULL; + loff_t pos = 3; /* skip '.', '..', and '.zfs' entries. */ + cred_t *cr; + int error; + xattr_filldir_t xf = { buffer_size, 0, buffer, ip }; + + cr = (cred_t *)get_current_cred(); + + /* Lookup the xattr directory */ + error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL); + if (error) { + if (error == -ENOENT) + error = 0; + + goto out; + } + + /* Fill provided buffer via zpl_zattr_filldir helper */ + error = -zfs_readdir(dxip, (void *)&xf, zpl_xattr_filldir, &pos, cr); + if (error) + goto out; + + error = xf.offset; +out: + if (dxip) + iput(dxip); + + put_cred(cr); + + return (error); +} + +static int +zpl_xattr_get(struct inode *ip, const char *name, void *buf, size_t size) +{ + struct inode *dxip = NULL; + struct inode *xip = NULL; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + + /* Lookup the xattr directory */ + error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL); + if (error) + goto out; + + /* Lookup a specific xattr name in the directory */ + error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL); + if (error) + goto out; + + if (!size) { + error = i_size_read(xip); + goto out; + } + + error = zpl_read_common(xip, buf, size, 0, UIO_SYSSPACE, 0, cr); +out: + if (xip) + iput(xip); + + if (dxip) + iput(dxip); + + put_cred(cr); + + if (error == -ENOENT) + error = -ENODATA; + + return (error); +} + +static int +zpl_xattr_set(struct inode *ip, const char *name, const void *value, + size_t size, int flags) +{ + struct inode *dxip = NULL; + struct inode *xip = NULL; + vattr_t *vap = NULL; + cred_t *cr; + ssize_t wrote; + int error; + + cr = (cred_t *)get_current_cred(); + + /* Lookup the xattr directory and create it if required. */ + error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR | CREATE_XATTR_DIR, + cr, NULL, NULL); + if (error) + goto out; + + /* + * Lookup a specific xattr name in the directory, two failure modes: + * XATTR_CREATE: fail if xattr already exists + * XATTR_REMOVE: fail if xattr does not exist + */ + error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL); + if (error) { + if (error != -ENOENT) + goto out; + + if ((error == -ENOENT) && (flags & XATTR_REPLACE)) + goto out; + } else { + error = -EEXIST; + if (flags & XATTR_CREATE) + goto out; + } + error = 0; + + /* Remove a specific name xattr when value is set to NULL. */ + if (value == NULL) { + if (xip) + error = -zfs_remove(dxip, (char *)name, cr); + + goto out; + } + + /* Lookup failed create a new xattr. */ + if (xip == NULL) { + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mode = S_IFREG | 0644; + vap->va_mask = ATTR_MODE; + vap->va_uid = current_fsuid(); + vap->va_gid = current_fsgid(); + + error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip, + cr, 0, NULL); + if (error) + goto out; + } + + ASSERT(xip != NULL); + wrote = zpl_write_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr); + if (wrote < 0) + error = wrote; + +out: + if (vap) + kmem_free(vap, sizeof(vattr_t)); + + if (xip) + iput(xip); + + if (dxip) + iput(dxip); + + put_cred(cr); + if (error == -ENOENT) + error = -ENODATA; + + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_xattr_user_get(struct inode *ip, const char *name, + void *buffer, size_t size) +{ + char *xattr_name; + int error; + + if (strcmp(name, "") == 0) + return -EINVAL; + + if (!(ITOZSB(ip)->z_flags & ZSB_XATTR_USER)) + return -EOPNOTSUPP; + + xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name); + error = zpl_xattr_get(ip, xattr_name, buffer, size); + strfree(xattr_name); + + return (error); +} + +static int +zpl_xattr_user_set(struct inode *ip, const char *name, + const void *value, size_t size, int flags) +{ + char *xattr_name; + int error; + + if (strcmp(name, "") == 0) + return -EINVAL; + + if (!(ITOZSB(ip)->z_flags & ZSB_XATTR_USER)) + return -EOPNOTSUPP; + + xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name); + error = zpl_xattr_set(ip, xattr_name, value, size, flags); + strfree(xattr_name); + + return (error); +} + +struct xattr_handler zpl_xattr_user_handler = { + .prefix = XATTR_USER_PREFIX, + .get = zpl_xattr_user_get, + .set = zpl_xattr_user_set, +}; + +static int +zpl_xattr_trusted_get(struct inode *ip, const char *name, + void *buffer, size_t size) +{ + char *xattr_name; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (strcmp(name, "") == 0) + return -EINVAL; + + xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name); + error = zpl_xattr_get(ip, xattr_name, buffer, size); + strfree(xattr_name); + + return (error); +} + +static int +zpl_xattr_trusted_set(struct inode *ip, const char *name, + const void *value, size_t size, int flags) +{ + char *xattr_name; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (strcmp(name, "") == 0) + return -EINVAL; + + xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name); + error = zpl_xattr_set(ip, xattr_name, value, size, flags); + strfree(xattr_name); + + return (error); +} + +struct xattr_handler zpl_xattr_trusted_handler = { + .prefix = XATTR_TRUSTED_PREFIX, + .get = zpl_xattr_trusted_get, + .set = zpl_xattr_trusted_set, +}; + +static int +zpl_xattr_security_get(struct inode *ip, const char *name, + void *buffer, size_t size) +{ + char *xattr_name; + int error; + + if (strcmp(name, "") == 0) + return -EINVAL; + + xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name); + error = zpl_xattr_get(ip, xattr_name, buffer, size); + strfree(xattr_name); + + return (error); +} + +static int +zpl_xattr_security_set(struct inode *ip, const char *name, + const void *value, size_t size, int flags) +{ + char *xattr_name; + int error; + + if (strcmp(name, "") == 0) + return -EINVAL; + + xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name); + error = zpl_xattr_set(ip, xattr_name, value, size, flags); + strfree(xattr_name); + + return (error); +} + +int +zpl_xattr_security_init(struct inode *ip, struct inode *dip) +{ + int error; + size_t len; + void *value; + char *name; + + error = security_inode_init_security(ip, dip, &name, &value, &len); + if (error) { + if (error == -EOPNOTSUPP) + return 0; + + return (error); + } + + error = zpl_xattr_security_set(ip, name, value, len, 0); + + kfree(name); + kfree(value); + + return (error); +} + +struct xattr_handler zpl_xattr_security_handler = { + .prefix = XATTR_SECURITY_PREFIX, + .get = zpl_xattr_security_get, + .set = zpl_xattr_security_set, +}; + +struct xattr_handler *zpl_xattr_handlers[] = { + &zpl_xattr_security_handler, + &zpl_xattr_trusted_handler, + &zpl_xattr_user_handler, +#ifdef HAVE_POSIX_ACLS + &zpl_xattr_acl_access_handler, + &zpl_xattr_acl_default_handler, +#endif /* HAVE_POSIX_ACLS */ +}; From c0d35759c5ab1abaa6b72062cc4ecd0d86628de8 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 3 Feb 2011 10:34:05 -0800 Subject: [PATCH 51/75] Add mmap(2) support It's worth taking a moment to describe how mmap is implemented for zfs because it differs considerably from other Linux filesystems. However, this issue is handled the same way under OpenSolaris. The issue is that by design zfs bypasses the Linux page cache and leaves all caching up to the ARC. This has been shown to work well for the common read(2)/write(2) case. However, mmap(2) is problem because it relies on being tightly integrated with the page cache. To handle this we cache mmap'ed files twice, once in the ARC and a second time in the page cache. The code is careful to keep both copies synchronized. When a file with an mmap'ed region is written to using write(2) both the data in the ARC and existing pages in the page cache are updated. For a read(2) data will be read first from the page cache then the ARC if needed. Neither a write(2) or read(2) will will ever result in new pages being added to the page cache. New pages are added to the page cache only via .readpage() which is called when the vfs needs to read a page off disk to back the virtual memory region. These pages may be modified without notifying the ARC and will be written out periodically via .writepage(). This will occur due to either a sync or the usual page aging behavior. Note because a read(2) of a mmap'ed file will always check the page cache first even when the ARC is out of date correct data will still be returned. While this implementation ensures correct behavior it does have have some drawbacks. The most obvious of which is that it increases the required memory footprint when access mmap'ed files. It also adds additional complexity to the code keeping both caches synchronized. Longer term it may be possible to cleanly resolve this wart by mapping page cache pages directly on to the ARC buffers. The Linux address space operations are flexible enough to allow selection of which pages back a particular index. The trick would be working out the details of which subsystem is in charge, the ARC, the page cache, or both. It may also prove helpful to move the ARC buffers to a scatter-gather lists rather than a vmalloc'ed region. Additionally, zfs_write/read_common() were used in the readpage and writepage hooks because it was fairly easy. However, it would be better to update zfs_fillpage and zfs_putapage to be Linux friendly and use them instead. --- include/sys/zfs_znode.h | 1 + module/zfs/zfs_vnops.c | 167 +++++++++++++++++-------------------- module/zfs/zpl_file.c | 177 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 243 insertions(+), 102 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 53bd18109..9d12a118e 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -210,6 +210,7 @@ typedef struct znode { sa_handle_t *z_sa_hdl; /* handle to sa data */ boolean_t z_is_sa; /* are we native sa? */ boolean_t z_is_zvol; /* are we used by the zvol */ + boolean_t z_is_mapped; /* are we mmap'ed */ struct inode z_inode; /* generic vfs inode */ } znode_t; diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index a8019ba5c..30b30891b 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -163,32 +163,7 @@ * return (error); // done, report error */ -#if defined(_KERNEL) && defined(HAVE_MMAP) -/* - * Utility functions to map and unmap a single physical page. These - * are used to manage the mappable copies of ZFS file data, and therefore - * do not update ref/mod bits. - */ -caddr_t -zfs_map_page(page_t *pp, enum seg_rw rw) -{ - if (kpm_enable) - return (hat_kpm_mapin(pp, 0)); - ASSERT(rw == S_READ || rw == S_WRITE); - return (ppmapin(pp, PROT_READ | ((rw == S_WRITE) ? PROT_WRITE : 0), - (caddr_t)-1)); -} - -void -zfs_unmap_page(page_t *pp, caddr_t addr) -{ - if (kpm_enable) { - hat_kpm_mapout(pp, 0, addr); - } else { - ppmapout(addr); - } -} - +#if defined(_KERNEL) /* * When a file is memory mapped, we must keep the IO data synchronized * between the DMU cache and the memory mapped pages. What this means: @@ -197,25 +172,39 @@ zfs_unmap_page(page_t *pp, caddr_t addr) * the page and the dmu buffer. */ static void -update_pages(struct inode *ip, int64_t start, int len, objset_t *os, - uint64_t oid) +update_pages(struct inode *ip, int64_t start, int len, + objset_t *os, uint64_t oid) { + struct address_space *mp = ip->i_mapping; + struct page *pp; + uint64_t nbytes; int64_t off; + void *pb; - off = start & PAGEOFFSET; - for (start &= PAGEMASK; len > 0; start += PAGESIZE) { - page_t *pp; - uint64_t nbytes = MIN(PAGESIZE - off, len); + off = start & (PAGE_CACHE_SIZE-1); + for (start &= PAGE_CACHE_MASK; len > 0; start += PAGE_CACHE_SIZE) { + nbytes = MIN(PAGE_CACHE_SIZE - off, len); - if (pp = page_lookup(ip, start, SE_SHARED)) { - caddr_t va; + pp = find_lock_page(mp, start >> PAGE_CACHE_SHIFT); + if (pp) { + if (mapping_writably_mapped(mp)) + flush_dcache_page(pp); - va = zfs_map_page(pp, S_WRITE); - (void) dmu_read(os, oid, start+off, nbytes, va+off, + pb = kmap(pp); + (void) dmu_read(os, oid, start+off, nbytes, pb+off, DMU_READ_PREFETCH); - zfs_unmap_page(pp, va); - page_unlock(pp); + kunmap(pp); + + if (mapping_writably_mapped(mp)) + flush_dcache_page(pp); + + mark_page_accessed(pp); + SetPageUptodate(pp); + ClearPageError(pp); + unlock_page(pp); + page_cache_release(pp); } + len -= nbytes; off = 0; } @@ -234,28 +223,39 @@ update_pages(struct inode *ip, int64_t start, int len, objset_t *os, static int mappedread(struct inode *ip, int nbytes, uio_t *uio) { + struct address_space *mp = ip->i_mapping; + struct page *pp; znode_t *zp = ITOZ(ip); objset_t *os = ITOZSB(ip)->z_os; int64_t start, off; + uint64_t bytes; int len = nbytes; int error = 0; + void *pb; start = uio->uio_loffset; - off = start & PAGEOFFSET; - for (start &= PAGEMASK; len > 0; start += PAGESIZE) { - page_t *pp; - uint64_t bytes = MIN(PAGESIZE - off, len); + off = start & (PAGE_CACHE_SIZE-1); + for (start &= PAGE_CACHE_MASK; len > 0; start += PAGE_CACHE_SIZE) { + bytes = MIN(PAGE_CACHE_SIZE - off, len); - if (pp = page_lookup(ip, start, SE_SHARED)) { - caddr_t va; + pp = find_lock_page(mp, start >> PAGE_CACHE_SHIFT); + if (pp) { + ASSERT(PageUptodate(pp)); - va = zfs_map_page(pp, S_READ); - error = uiomove(va + off, bytes, UIO_READ, uio); - zfs_unmap_page(pp, va); - page_unlock(pp); + pb = kmap(pp); + error = uiomove(pb + off, bytes, UIO_READ, uio); + kunmap(pp); + + if (mapping_writably_mapped(mp)) + flush_dcache_page(pp); + + mark_page_accessed(pp); + unlock_page(pp); + page_cache_release(pp); } else { error = dmu_read_uio(os, zp->z_id, uio, bytes); } + len -= bytes; off = 0; if (error) @@ -263,7 +263,7 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio) } return (error); } -#endif /* _KERNEL && HAVE_MMAP */ +#endif /* _KERNEL */ offset_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */ @@ -273,7 +273,8 @@ offset_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */ * IN: ip - inode of file to be read from. * uio - structure supplying read location, range info, * and return buffer. - * ioflag - SYNC flags; used to provide FRSYNC semantics. + * ioflag - FSYNC flags; used to provide FRSYNC semantics. + * O_DIRECT flag; used to bypass page cache. * cr - credentials of caller. * * OUT: uio - updated offset and range, buffer filled. @@ -394,15 +395,11 @@ zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr) nbytes = MIN(n, zfs_read_chunk_size - P2PHASE(uio->uio_loffset, zfs_read_chunk_size)); -/* XXX: Drop this, ARC update handled by zpl layer */ -#ifdef HAVE_MMAP - if (vn_has_cached_data(ip)) + if (zp->z_is_mapped && !(ioflag & O_DIRECT)) error = mappedread(ip, nbytes, uio); else error = dmu_read_uio(os, zp->z_id, uio, nbytes); -#else - error = dmu_read_uio(os, zp->z_id, uio, nbytes); -#endif /* HAVE_MMAP */ + if (error) { /* convert checksum errors into IO errors */ if (error == ECKSUM) @@ -429,6 +426,7 @@ EXPORT_SYMBOL(zfs_read); * uio - structure supplying write location, range info, * and data buffer. * ioflag - FAPPEND flag set if in append mode. + * O_DIRECT flag; used to bypass page cache. * cr - credentials of caller. * * OUT: uio - updated offset and range. @@ -700,13 +698,9 @@ again: ASSERT(tx_bytes <= uio->uio_resid); uioskip(uio, tx_bytes); } -/* XXX: Drop this, ARC update handled by zpl layer */ -#ifdef HAVE_MMAP - if (tx_bytes && vn_has_cached_data(ip)) { - update_pages(ip, woff, - tx_bytes, zsb->z_os, zp->z_id); - } -#endif /* HAVE_MMAP */ + + if (tx_bytes && zp->z_is_mapped && !(ioflag & O_DIRECT)) + update_pages(ip, woff, tx_bytes, zsb->z_os, zp->z_id); /* * If we made no progress, we're done. If we made even @@ -3392,6 +3386,7 @@ top: } EXPORT_SYMBOL(zfs_link); +#ifdef HAVE_MMAP /* * zfs_null_putapage() is used when the file system has been force * unmounted. It just drops the pages. @@ -3627,48 +3622,30 @@ out: ZFS_EXIT(zfsvfs); return (error); } +#endif /* HAVE_MMAP */ /*ARGSUSED*/ void -zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) +zfs_inactive(struct inode *ip) { - znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs = zp->z_zfsvfs; + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); int error; - rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER); - if (zp->z_sa_hdl == NULL) { - /* - * The fs has been unmounted, or we did a - * suspend/resume and this file no longer exists. - */ - if (vn_has_cached_data(vp)) { - (void) pvn_vplist_dirty(vp, 0, zfs_null_putapage, - B_INVAL, cr); - } + truncate_inode_pages(&ip->i_data, 0); - mutex_enter(&zp->z_lock); - mutex_enter(&vp->v_lock); - ASSERT(vp->v_count == 1); - vp->v_count = 0; - mutex_exit(&vp->v_lock); - mutex_exit(&zp->z_lock); - rw_exit(&zfsvfs->z_teardown_inactive_lock); - zfs_znode_free(zp); +#ifdef HAVE_SNAPSHOT + /* Early return for snapshot inode? */ +#endif /* HAVE_SNAPSHOT */ + + rw_enter(&zsb->z_teardown_inactive_lock, RW_READER); + if (zp->z_sa_hdl == NULL) { + rw_exit(&zsb->z_teardown_inactive_lock); return; } - /* - * Attempt to push any data in the page cache. If this fails - * we will get kicked out later in zfs_zinactive(). - */ - if (vn_has_cached_data(vp)) { - (void) pvn_vplist_dirty(vp, 0, zfs_putapage, B_INVAL|B_ASYNC, - cr); - } - if (zp->z_atime_dirty && zp->z_unlinked == 0) { - dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os); + dmu_tx_t *tx = dmu_tx_create(zsb->z_os); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); @@ -3712,6 +3689,7 @@ zfs_seek(struct inode *ip, offset_t ooff, offset_t *noffp, } EXPORT_SYMBOL(zfs_seek); +#ifdef HAVE_MMAP /* * Pre-filter the generic locking function to trap attempts to place * a mandatory lock on a memory mapped file. @@ -4056,6 +4034,7 @@ zfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, return (0); } +#endif /* HAVE_MMAP */ /* * convoff - converts the given data (start, whence) to the diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index 41901bb6c..585f971e8 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -145,24 +145,185 @@ zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) return (wrote); } +/* + * It's worth taking a moment to describe how mmap is implemented + * for zfs because it differs considerably from other Linux filesystems. + * However, this issue is handled the same way under OpenSolaris. + * + * The issue is that by design zfs bypasses the Linux page cache and + * leaves all caching up to the ARC. This has been shown to work + * well for the common read(2)/write(2) case. However, mmap(2) + * is problem because it relies on being tightly integrated with the + * page cache. To handle this we cache mmap'ed files twice, once in + * the ARC and a second time in the page cache. The code is careful + * to keep both copies synchronized. + * + * When a file with an mmap'ed region is written to using write(2) + * both the data in the ARC and existing pages in the page cache + * are updated. For a read(2) data will be read first from the page + * cache then the ARC if needed. Neither a write(2) or read(2) will + * will ever result in new pages being added to the page cache. + * + * New pages are added to the page cache only via .readpage() which + * is called when the vfs needs to read a page off disk to back the + * virtual memory region. These pages may be modified without + * notifying the ARC and will be written out periodically via + * .writepage(). This will occur due to either a sync or the usual + * page aging behavior. Note because a read(2) of a mmap'ed file + * will always check the page cache first even when the ARC is out + * of date correct data will still be returned. + * + * While this implementation ensures correct behavior it does have + * have some drawbacks. The most obvious of which is that it + * increases the required memory footprint when access mmap'ed + * files. It also adds additional complexity to the code keeping + * both caches synchronized. + * + * Longer term it may be possible to cleanly resolve this wart by + * mapping page cache pages directly on to the ARC buffers. The + * Linux address space operations are flexible enough to allow + * selection of which pages back a particular index. The trick + * would be working out the details of which subsystem is in + * charge, the ARC, the page cache, or both. It may also prove + * helpful to move the ARC buffers to a scatter-gather lists + * rather than a vmalloc'ed region. + */ +static int +zpl_mmap(struct file *filp, struct vm_area_struct *vma) +{ + znode_t *zp = ITOZ(filp->f_mapping->host); + int error; + + error = generic_file_mmap(filp, vma); + if (error) + return (error); + + mutex_enter(&zp->z_lock); + zp->z_is_mapped = 1; + mutex_exit(&zp->z_lock); + + return (error); +} + +/* + * Populate a page with data for the Linux page cache. This function is + * only used to support mmap(2). There will be an identical copy of the + * data in the ARC which is kept up to date via .write() and .writepage(). + * + * Current this function relies on zpl_read_common() and the O_DIRECT + * flag to read in a page. This works but the more correct way is to + * update zfs_fillpage() to be Linux friendly and use that interface. + */ +static int +zpl_readpage(struct file *filp, struct page *pp) +{ + struct inode *ip; + loff_t off, i_size; + size_t len, wrote; + cred_t *cr; + void *pb; + int error = 0; + + ASSERT(PageLocked(pp)); + ip = pp->mapping->host; + off = page_offset(pp); + i_size = i_size_read(ip); + ASSERT3S(off, <, i_size); + + cr = (cred_t *)get_current_cred(); + len = MIN(PAGE_CACHE_SIZE, i_size - off); + + pb = kmap(pp); + + /* O_DIRECT is passed to bypass the page cache and avoid deadlock. */ + wrote = zpl_read_common(ip, pb, len, off, UIO_SYSSPACE, O_DIRECT, cr); + if (wrote != len) + error = -EIO; + + if (!error && (len < PAGE_CACHE_SIZE)) + memset(pb + len, 0, PAGE_CACHE_SIZE - len); + + kunmap(pp); + put_cred(cr); + + if (error) { + SetPageError(pp); + ClearPageUptodate(pp); + } else { + ClearPageError(pp); + SetPageUptodate(pp); + flush_dcache_page(pp); + } + + unlock_page(pp); + + return (error); +} + +/* + * Write out dirty pages to the ARC, this function is only required to + * support mmap(2). Mapped pages may be dirtied by memory operations + * which never call .write(). These dirty pages are kept in sync with + * the ARC buffers via this hook. + * + * Currently this function relies on zpl_write_common() and the O_DIRECT + * flag to push out the page. This works but the more correct way is + * to update zfs_putapage() to be Linux friendly and use that interface. + */ +static int +zpl_writepage(struct page *pp, struct writeback_control *wbc) +{ + struct inode *ip; + loff_t off, i_size; + size_t len, read; + cred_t *cr; + void *pb; + int error = 0; + + ASSERT(PageLocked(pp)); + ip = pp->mapping->host; + off = page_offset(pp); + i_size = i_size_read(ip); + + cr = (cred_t *)get_current_cred(); + len = MIN(PAGE_CACHE_SIZE, i_size - off); + + pb = kmap(pp); + + /* O_DIRECT is passed to bypass the page cache and avoid deadlock. */ + read = zpl_write_common(ip, pb, len, off, UIO_SYSSPACE, O_DIRECT, cr); + if (read != len) + error = -EIO; + + kunmap(pp); + put_cred(cr); + + if (error) { + SetPageError(pp); + ClearPageUptodate(pp); + } else { + ClearPageError(pp); + SetPageUptodate(pp); + } + + unlock_page(pp); + + return (error); +} + const struct address_space_operations zpl_address_space_operations = { -#if 0 .readpage = zpl_readpage, .writepage = zpl_writepage, - .direct_IO = zpl_direct_IO, -#endif }; const struct file_operations zpl_file_operations = { .open = generic_file_open, .llseek = generic_file_llseek, - .read = zpl_read, /* do_sync_read */ - .write = zpl_write, /* do_sync_write */ + .read = zpl_read, + .write = zpl_write, .readdir = zpl_readdir, - .mmap = generic_file_mmap, + .mmap = zpl_mmap, .fsync = zpl_fsync, - .aio_read = NULL, /* generic_file_aio_read */ - .aio_write = NULL, /* generic_file_aio_write */ }; const struct file_operations zpl_dir_file_operations = { From 8926ab7a50d60d855e4d49d2ed7bdef49dd56149 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 4 Feb 2011 14:38:11 -0800 Subject: [PATCH 52/75] Move cv_destroy() outside zp->z_range_lock() With the recent SPL change (d599e4fa) that forces cv_destroy() to block until all waiters have been woken. It is now unsafe to call cv_destroy() under the zp->z_range_lock() because it is used as the condition variable mutex. If there are waiters cv_destroy() will block until they wake up and aquire the mutex. However, they will never aquire the mutex because cv_destroy() will not return allowing it's caller to drop the lock. Deadlock. To avoid this cv_destroy() is now run asynchronously in a taskq. This solves two problems: 1) It is no longer run under the zp->z_range_lock so no deadlock. 2) Since cv_destroy() may now block we don't want this slowing down zfs_range_unlock() and throttling the system. This was not as much of an issue under OpenSolaris because their cv_destroy() implementation does not do anything. They do however risk a bad paging request if cv_destroy() returns, the memory holding the condition variable is free'd, and then the waiters wake up and try to reference it. It's a very small unlikely race, but it is possible. --- module/zfs/zfs_rlock.c | 59 ++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/module/zfs/zfs_rlock.c b/module/zfs/zfs_rlock.c index 9362fb4e8..26ad58de8 100644 --- a/module/zfs/zfs_rlock.c +++ b/module/zfs/zfs_rlock.c @@ -453,6 +453,20 @@ zfs_range_lock(znode_t *zp, uint64_t off, uint64_t len, rl_type_t type) return (new); } +static void +zfs_range_free(void *arg) +{ + rl_t *rl = arg; + + if (rl->r_write_wanted) + cv_destroy(&rl->r_wr_cv); + + if (rl->r_read_wanted) + cv_destroy(&rl->r_rd_cv); + + kmem_free(rl, sizeof (rl_t)); +} + /* * Unlock a reader lock */ @@ -472,14 +486,14 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove) */ if (remove->r_cnt == 1) { avl_remove(tree, remove); - if (remove->r_write_wanted) { + mutex_exit(&zp->z_range_lock); + if (remove->r_write_wanted) cv_broadcast(&remove->r_wr_cv); - cv_destroy(&remove->r_wr_cv); - } - if (remove->r_read_wanted) { + + if (remove->r_read_wanted) cv_broadcast(&remove->r_rd_cv); - cv_destroy(&remove->r_rd_cv); - } + + taskq_dispatch(system_taskq, zfs_range_free, remove, 0); } else { ASSERT3U(remove->r_cnt, ==, 0); ASSERT3U(remove->r_write_wanted, ==, 0); @@ -505,19 +519,21 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove) rl->r_cnt--; if (rl->r_cnt == 0) { avl_remove(tree, rl); - if (rl->r_write_wanted) { + + if (rl->r_write_wanted) cv_broadcast(&rl->r_wr_cv); - cv_destroy(&rl->r_wr_cv); - } - if (rl->r_read_wanted) { + + if (rl->r_read_wanted) cv_broadcast(&rl->r_rd_cv); - cv_destroy(&rl->r_rd_cv); - } - kmem_free(rl, sizeof (rl_t)); + + taskq_dispatch(system_taskq, + zfs_range_free, rl, 0); } } + + mutex_exit(&zp->z_range_lock); + kmem_free(remove, sizeof (rl_t)); } - kmem_free(remove, sizeof (rl_t)); } /* @@ -537,22 +553,19 @@ zfs_range_unlock(rl_t *rl) /* writer locks can't be shared or split */ avl_remove(&zp->z_range_avl, rl); mutex_exit(&zp->z_range_lock); - if (rl->r_write_wanted) { + if (rl->r_write_wanted) cv_broadcast(&rl->r_wr_cv); - cv_destroy(&rl->r_wr_cv); - } - if (rl->r_read_wanted) { + + if (rl->r_read_wanted) cv_broadcast(&rl->r_rd_cv); - cv_destroy(&rl->r_rd_cv); - } - kmem_free(rl, sizeof (rl_t)); + + taskq_dispatch(system_taskq, zfs_range_free, rl, 0); } else { /* * lock may be shared, let zfs_range_unlock_reader() - * release the lock and free the rl_t + * release the zp->z_range_lock lock and free the rl_t */ zfs_range_unlock_reader(zp, rl); - mutex_exit(&zp->z_range_lock); } } From b3b4f547f9243c0c1a446c74574a1f737e29dee6 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 4 Feb 2011 16:17:54 -0800 Subject: [PATCH 53/75] Remove useless libefi warnings These two warnings in libefi serve no real purpose. When running without DEBUG they are already supressed, and even when DEBUG is enabled all they indicate is the device doesn't already have an EFI label. For a Linux machine this is probably the common case. --- lib/libefi/rdwr_efi.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/lib/libefi/rdwr_efi.c b/lib/libefi/rdwr_efi.c index da71e3486..2af0c4e2e 100644 --- a/lib/libefi/rdwr_efi.c +++ b/lib/libefi/rdwr_efi.c @@ -269,19 +269,12 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc) struct uuid uuid; struct dk_cinfo dki_info; - if (read_disk_info(fd, &capacity, &lbsize) != 0) { - if (efi_debug) - (void) fprintf(stderr, - "couldn't read disk information\n"); + if (read_disk_info(fd, &capacity, &lbsize) != 0) return (-1); - } + #if defined(__linux__) - if (efi_get_info(fd, &dki_info) != 0) { - if (efi_debug) - (void) fprintf(stderr, - "couldn't read disk information\n"); + if (efi_get_info(fd, &dki_info) != 0) return (-1); - } if (dki_info.dki_partition != 0) return (-1); From ceb43b935d6c4f4f6509623c7498d5dcc40ea813 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 4 Feb 2011 16:54:34 -0800 Subject: [PATCH 54/75] Invalidate dcache and inode cache When performing a 'zfs rollback' it's critical to invalidate the previous dcache and inode cache. If we don't there will stale cache entries which when accessed will result in EIOs. --- module/zfs/zfs_vfsops.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 1763d171a..bb2fdb029 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1071,17 +1071,17 @@ zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting) rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG); -#ifdef HAVE_DNLC if (!unmounting) { /* - * We purge the parent filesystem's vfsp as the parent - * filesystem and all of its snapshots have their vnode's - * v_vfsp set to the parent's filesystem's vfsp. Note, - * 'z_parent' is self referential for non-snapshots. + * We purge the parent filesystem's super block as the + * parent filesystem and all of its snapshots have their + * inode's super block set to the parent's filesystem's + * super block. Note, 'z_parent' is self referential + * for non-snapshots. */ - (void) dnlc_purge_vfsp(zsb->z_parent->z_vfs, 0); + shrink_dcache_sb(zsb->z_parent->z_sb); + invalidate_inodes(zsb->z_parent->z_sb); } -#endif /* HAVE_DNLC */ /* * Close the zil. NB: Can't close the zil while zfs_inactive From f44b46a632d5b332d993faaeb16fe30650619803 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 7 Feb 2011 12:09:23 -0800 Subject: [PATCH 55/75] Update META to 0.6.0 Roll the version forward to 0.6.0, the addition of the Posix layer warrents updating the major version number. --- META | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/META b/META index 6ecc7a614..d9f9e0912 100644 --- a/META +++ b/META @@ -1,7 +1,7 @@ Meta: 1 Name: zfs Branch: 1.0 -Version: 0.5.2 +Version: 0.6.0 Release: 1 Release-Tags: relext License: CDDL From 4db77a74a6a26c57a04f98c4a23b9fda9319ba9f Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 7 Feb 2011 12:21:29 -0800 Subject: [PATCH 56/75] Suppress large kmem_alloc() warning The following warning was observed under normal operation. It's not fatal but it's something to be addressed long term. Flag the offending allocation with KM_NODEBUG to suppress the warning and flag the call site. SPL: Showing stack for process 21761 Pid: 21761, comm: iozone Tainted: P ---------------- 2.6.32-71.14.1.el6.x86_64 #1 Call Trace: [] spl_debug_dumpstack+0x27/0x40 [spl] [] kmem_alloc_debug+0x11d/0x130 [spl] [] dmu_buf_hold_array_by_dnode+0xa6/0x4e0 [zfs] [] dmu_buf_hold_array+0x65/0x90 [zfs] [] dmu_read_uio+0x41/0xd0 [zfs] [] zfs_read+0x147/0x470 [zfs] [] zpl_read_common+0x52/0x70 [zfs] [] zpl_read+0x43/0x70 [zfs] [] vfs_read+0xb5/0x1a0 [] sys_read+0x51/0x90 [] system_call_fastpath+0x16/0x1b --- module/zfs/dmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index ede0d0517..04b02c7d2 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -381,7 +381,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length, } nblks = 1; } - dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP); + dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP | KM_NODEBUG); if (dn->dn_objset->os_dsl_dataset) dp = dn->dn_objset->os_dsl_dataset->ds_dir->dd_pool; From 6839eed23e3c9d85cf0de767be32af0759e5bf2d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 7 Feb 2011 13:54:59 -0800 Subject: [PATCH 57/75] Use 'noop' IO Scheduler Initial testing has shown the the right IO scheduler to use under Linux is noop. This strikes the ideal balance by allowing the zfs elevator to do all request ordering and prioritization. While allowing the Linux elevator to do the maximum front/back merging allowed by the physical device. This yields the largest possible requests for the device with the lowest total overhead. While 'noop' should be right for your system you can choose a different IO scheduler with the 'zfs_vdev_scheduler' option. You may set this value to any of the standard Linux schedulers: noop, cfq, deadline, anticipatory. In addition, if you choose 'none' zfs will not attempt to change the IO scheduler for the block device. --- include/sys/vdev_disk.h | 3 +++ module/zfs/vdev_disk.c | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/sys/vdev_disk.h b/include/sys/vdev_disk.h index 021e66d1a..03e7048ac 100644 --- a/include/sys/vdev_disk.h +++ b/include/sys/vdev_disk.h @@ -81,6 +81,9 @@ extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **); # define vdev_bdev_block_size(bdev) bdev_hardsect_size(bdev) #endif +/* Default Linux IO Scheduler */ +#define VDEV_SCHEDULER "noop" + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index 3e59bd226..aba3c4ab5 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -33,6 +33,8 @@ #include #include +char *zfs_vdev_scheduler = VDEV_SCHEDULER; + /* * Virtual device vector for disks. */ @@ -102,6 +104,43 @@ vdev_disk_error(zio_t *zio) #endif } +/* + * Use the Linux 'noop' elevator for zfs managed block devices. This + * strikes the ideal balance by allowing the zfs elevator to do all + * request ordering and prioritization. While allowing the Linux + * elevator to do the maximum front/back merging allowed by the + * physical device. This yields the largest possible requests for + * the device with the lowest total overhead. + * + * Unfortunately we cannot directly call the elevator_switch() function + * because it is not exported from the block layer. This means we have + * to use the sysfs interface and a user space upcall. Pools will be + * automatically imported on module load so we must do this at device + * open time from the kernel. + */ +static int +vdev_elevator_switch(vdev_t *v, char *elevator, char *device) +{ + char sh_path[] = "/bin/sh"; + char sh_cmd[128]; + char *argv[] = { sh_path, "-c", sh_cmd }; + char *envp[] = { NULL }; + int error; + + if (!strncmp(elevator, "none", 4) && (strlen(elevator) == 4)) + return (0); + + sprintf(sh_cmd, "%s \"%s\" >/sys/block/%s/queue/scheduler", + "/bin/echo", elevator, device); + + error = call_usermodehelper(sh_path, argv, envp, 1); + if (error) + printk("ZFS: Unable to set \"%s\" scheduler for %s (%s): %d\n", + elevator, v->vdev_path, device, error); + + return (error); +} + static int vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift) { @@ -167,6 +206,10 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift) /* Based on the minimum sector size set the block size */ *ashift = highbit(MAX(block_size, SPA_MINBLOCKSIZE)) - 1; + /* Try to set the io scheduler elevator algorithm */ + (void) vdev_elevator_switch(v, zfs_vdev_scheduler, + bdev->bd_disk->disk_name); + return 0; } @@ -702,3 +745,6 @@ vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config) return 0; } + +module_param(zfs_vdev_scheduler, charp, 0644); +MODULE_PARM_DESC(zfs_vdev_scheduler, "IO Scheduler (noop)"); From 6c9e06f14de1ed27e6032be2197b8f4cbec7405a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 8 Feb 2011 15:40:52 -0800 Subject: [PATCH 58/75] Update AUTHORS file This file has gotten stale and needed to be updated. There are individuals who deserve to be recognized for their contributions to the project. I've done my best to assemble names from the commit logs of those who have submitted patches. This list may not be comprehensive, if you feel I've overlooked your contribution please let me know and we can get your name added. --- AUTHORS | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 04ebc204f..e2c474f19 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,34 @@ -Brian Behlendorf , -Herb Wartens , -Jim Garlick , -Ricardo M. Correia +Brian Behlendorf is the principle developer of the ZFS on Linux port. +He works full time as a computer scientist at Lawrence Livermore +National Laboratory on the ZFS and Lustre filesystems. However, +this port would not have been possible without the help of many +others who have contributed their time, effort, and insight. + + Brian Behlendorf + +First and foremost the hard working ZFS developers at Sun/Oracle. +They are responsible for the bulk of the code in this project and +without their efforts there never would have been a ZFS filesystem. + + The ZFS Development Team at Sun/Oracle + +Next all the developers at KQ Infotech who implemented a working +ZFS Posix Layer (ZPL) for this port. Their implementation provided +an excellent reference for adding the missing ZPL functionality. + + Anand Mitra + Anurag Agarwal + Neependra Khare + Prasad Joshi + Rohan Puri + Sandip Divekar + Shoaib + Shrirang + +Additionally the following individuals have all made contributions +to the project and deserve to be acknowledged. + + Ricardo M. Correia + Ned Bass + Herb Wartens + Jim Garlick From 1ac0ea38a5b19771b0dfbc6b2244c4f674ef1a31 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 10 Feb 2011 10:57:29 -0800 Subject: [PATCH 59/75] Add missing -ldl linker option The inclusion on dlsym(), dlopen(), and dlclose() symbols require us to link against the dl library. Be careful to add the flag to both the libzfs library and the commands which depend on the library. --- cmd/zdb/Makefile.am | 2 +- cmd/zdb/Makefile.in | 2 +- cmd/zfs/Makefile.am | 2 +- cmd/zfs/Makefile.in | 2 +- cmd/zinject/Makefile.am | 2 +- cmd/zinject/Makefile.in | 2 +- cmd/zpool/Makefile.am | 2 +- cmd/zpool/Makefile.in | 2 +- lib/libzfs/Makefile.am | 2 +- lib/libzfs/Makefile.in | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/zdb/Makefile.am b/cmd/zdb/Makefile.am index 16d749991..9304bfc0a 100644 --- a/cmd/zdb/Makefile.am +++ b/cmd/zdb/Makefile.am @@ -20,4 +20,4 @@ zdb_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zdb_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zdb_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index ce17224a1..08f8377e3 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -311,7 +311,7 @@ zdb_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zdb_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zdb_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) all: all-am .SUFFIXES: diff --git a/cmd/zfs/Makefile.am b/cmd/zfs/Makefile.am index ba3e6447e..1b7cd841c 100644 --- a/cmd/zfs/Makefile.am +++ b/cmd/zfs/Makefile.am @@ -22,4 +22,4 @@ zfs_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zfs_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zfs_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index 654a3814e..44fff71f1 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -313,7 +313,7 @@ zfs_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zfs_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zfs_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) all: all-am .SUFFIXES: diff --git a/cmd/zinject/Makefile.am b/cmd/zinject/Makefile.am index df97db372..eb67b1569 100644 --- a/cmd/zinject/Makefile.am +++ b/cmd/zinject/Makefile.am @@ -21,4 +21,4 @@ zinject_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zinject_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zinject_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index daced68ab..114128100 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -312,7 +312,7 @@ zinject_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zinject_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zinject_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) all: all-am .SUFFIXES: diff --git a/cmd/zpool/Makefile.am b/cmd/zpool/Makefile.am index a0d16466e..d3ca0612a 100644 --- a/cmd/zpool/Makefile.am +++ b/cmd/zpool/Makefile.am @@ -23,4 +23,4 @@ zpool_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zpool_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zpool_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index a6f96f7be..f800e6bc0 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -315,7 +315,7 @@ zpool_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la -zpool_LDFLAGS = -pthread -lm $(ZLIB) -lrt $(LIBUUID) $(LIBBLKID) +zpool_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID) all: all-am .SUFFIXES: diff --git a/lib/libzfs/Makefile.am b/lib/libzfs/Makefile.am index de5212234..f6b0b0594 100644 --- a/lib/libzfs/Makefile.am +++ b/lib/libzfs/Makefile.am @@ -6,7 +6,7 @@ DEFAULT_INCLUDES += \ lib_LTLIBRARIES = libzfs.la -libzfs_la_LDFLAGS = -lm $(LIBSELINUX) +libzfs_la_LDFLAGS = -lm -ldl $(LIBSELINUX) libzfs_la_LIBADD = \ $(top_builddir)/lib/libefi/libefi.la \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index cad8e6c33..1dbecc335 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -315,7 +315,7 @@ AM_CFLAGS = -Wall -Wstrict-prototypes -fno-strict-aliasing \ -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64 \ -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\" lib_LTLIBRARIES = libzfs.la -libzfs_la_LDFLAGS = -lm $(LIBSELINUX) +libzfs_la_LDFLAGS = -lm -ldl $(LIBSELINUX) libzfs_la_LIBADD = \ $(top_builddir)/lib/libefi/libefi.la \ $(top_builddir)/lib/libuutil/libuutil.la From afffb5cd102f340f3879f4d7af8988dd209b9b72 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 10 Feb 2011 12:11:05 -0800 Subject: [PATCH 60/75] MS_DIRSYNC and MS_REC compat It turns out that older versions of the glibc headers do not properly define MS_DIRSYNC despite it being explicitly mentioned in the man pages. They instead call it S_WRITE, so for system where this is not correct defined map MS_DIRSYNC to S_WRITE. At the time of this commit both Ubuntu Lucid, and Debian Squeeze both use the out of date glibc headers. As for MS_REC this field is also not available in the older headers. Since there is no obvious mapping in this case we simply disable the recursive mount option which used it. --- cmd/zfs/zfs_main.c | 2 ++ lib/libspl/include/sys/mount.h | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index d27fcbf46..86f0d5c39 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -3875,7 +3875,9 @@ static const option_map_t option_map[] = { #endif /* Valid options not found in mount(8) */ { MNTOPT_BIND, MS_BIND }, +#ifdef MS_REC { MNTOPT_RBIND, MS_BIND|MS_REC }, +#endif { MNTOPT_COMMENT, MS_COMMENT }, { MNTOPT_BOOTWAIT, MS_COMMENT }, { MNTOPT_NOBOOTWAIT, MS_COMMENT }, diff --git a/lib/libspl/include/sys/mount.h b/lib/libspl/include/sys/mount.h index f6a67c6a0..9eb893fe6 100644 --- a/lib/libspl/include/sys/mount.h +++ b/lib/libspl/include/sys/mount.h @@ -42,6 +42,15 @@ #define BLKGETSIZE64 _IOR(0x12, 114, size_t) #endif +/* + * Some old glibc headers don't correctly define MS_DIRSYNC and + * instead use the enum name S_WRITE. When using these older + * headers define MS_DIRSYNC to be S_WRITE. + */ +#if !defined(MS_DIRSYNC) +#define MS_DIRSYNC S_WRITE +#endif + #define MS_USERS 0x40000000 #define MS_OWNER 0x10000000 #define MS_GROUP 0x08000000 From 1b94c25ceb12649b4b2ffb9a016e4f51cfa91736 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 10 Feb 2011 14:54:33 -0800 Subject: [PATCH 61/75] Prefer /lib/modules/$(uname -r)/ links Preferentially use the /lib/modules/$(uname -r)/source and /lib/modules/$(uname -r)/build links. Only if neither of these links exist fallback to alternate methods for deducing which kernel to build with. This resolves the need to manually specify --with-linux= and --with-linux-obj= on Debian systems. --- config/kernel.m4 | 11 ++++++++--- configure | 22 ++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/config/kernel.m4 b/config/kernel.m4 index c2fc5a098..2c83dc590 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -78,8 +78,11 @@ AC_DEFUN([ZFS_AC_KERNEL], [ AC_MSG_CHECKING([kernel source directory]) if test -z "$kernelsrc"; then - headersdir="/lib/modules/$(uname -r)/build" - if test -e "$headersdir"; then + if test -e "/lib/modules/$(uname -r)/source"; then + headersdir="/lib/modules/$(uname -r)/source" + sourcelink=$(readlink -f "$headersdir") + elif test -e "/lib/modules/$(uname -r)/build"; then + headersdir="/lib/modules/$(uname -r)/build" sourcelink=$(readlink -f "$headersdir") else sourcelink=$(ls -1d /usr/src/kernels/* \ @@ -105,7 +108,9 @@ AC_DEFUN([ZFS_AC_KERNEL], [ AC_MSG_RESULT([$kernelsrc]) AC_MSG_CHECKING([kernel build directory]) if test -z "$kernelbuild"; then - if test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then + if test -e "/lib/modules/$(uname -r)/build"; then + kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` + elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} elif test -d ${kernelsrc}-obj/${target_cpu}/default; then kernelbuild=${kernelsrc}-obj/${target_cpu}/default diff --git a/configure b/configure index e76d64ddf..716a73fee 100755 --- a/configure +++ b/configure @@ -11856,8 +11856,11 @@ fi { $as_echo "$as_me:$LINENO: checking kernel source directory" >&5 $as_echo_n "checking kernel source directory... " >&6; } if test -z "$kernelsrc"; then - headersdir="/lib/modules/$(uname -r)/build" - if test -e "$headersdir"; then + if test -e "/lib/modules/$(uname -r)/source"; then + headersdir="/lib/modules/$(uname -r)/source" + sourcelink=$(readlink -f "$headersdir") + elif test -e "/lib/modules/$(uname -r)/build"; then + headersdir="/lib/modules/$(uname -r)/build" sourcelink=$(readlink -f "$headersdir") else sourcelink=$(ls -1d /usr/src/kernels/* \ @@ -11891,7 +11894,9 @@ $as_echo "$kernelsrc" >&6; } { $as_echo "$as_me:$LINENO: checking kernel build directory" >&5 $as_echo_n "checking kernel build directory... " >&6; } if test -z "$kernelbuild"; then - if test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then + if test -e "/lib/modules/$(uname -r)/build"; then + kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` + elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} elif test -d ${kernelsrc}-obj/${target_cpu}/default; then kernelbuild=${kernelsrc}-obj/${target_cpu}/default @@ -15378,8 +15383,11 @@ fi { $as_echo "$as_me:$LINENO: checking kernel source directory" >&5 $as_echo_n "checking kernel source directory... " >&6; } if test -z "$kernelsrc"; then - headersdir="/lib/modules/$(uname -r)/build" - if test -e "$headersdir"; then + if test -e "/lib/modules/$(uname -r)/source"; then + headersdir="/lib/modules/$(uname -r)/source" + sourcelink=$(readlink -f "$headersdir") + elif test -e "/lib/modules/$(uname -r)/build"; then + headersdir="/lib/modules/$(uname -r)/build" sourcelink=$(readlink -f "$headersdir") else sourcelink=$(ls -1d /usr/src/kernels/* \ @@ -15413,7 +15421,9 @@ $as_echo "$kernelsrc" >&6; } { $as_echo "$as_me:$LINENO: checking kernel build directory" >&5 $as_echo_n "checking kernel build directory... " >&6; } if test -z "$kernelbuild"; then - if test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then + if test -e "/lib/modules/$(uname -r)/build"; then + kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` + elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} elif test -d ${kernelsrc}-obj/${target_cpu}/default; then kernelbuild=${kernelsrc}-obj/${target_cpu}/default From 777d4af89137907adc91377327505f40c296035d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 10 Feb 2011 16:16:52 -0800 Subject: [PATCH 62/75] Linux 2.6.35 compat, const struct xattr_handler The const keyword was added to the 'struct xattr_handler' in the generic Linux super_block structure. To handle this we define an appropriate xattr_handler_t typedef which can be used. This was the preferred solution because it keeps the code clean and readable. --- Makefile.in | 1 + cmd/Makefile.in | 1 + cmd/zdb/Makefile.in | 1 + cmd/zfs/Makefile.in | 1 + cmd/zinject/Makefile.in | 1 + cmd/zpios/Makefile.in | 1 + cmd/zpool/Makefile.in | 1 + cmd/zpool_id/Makefile.in | 1 + cmd/zpool_layout/Makefile.in | 1 + cmd/ztest/Makefile.in | 1 + config/kernel-xattr-handler.m4 | 32 ++++ config/kernel.m4 | 1 + configure | 154 ++++++++++++++++++++ etc/Makefile.in | 1 + include/Makefile.in | 1 + include/linux/Makefile.am | 1 + include/linux/Makefile.in | 2 + include/linux/xattr_compat.h | 42 ++++++ include/sys/Makefile.in | 1 + include/sys/fm/Makefile.in | 1 + include/sys/fm/fs/Makefile.in | 1 + include/sys/fs/Makefile.in | 1 + include/sys/zpl.h | 3 +- lib/Makefile.in | 1 + lib/libavl/Makefile.in | 1 + lib/libefi/Makefile.in | 1 + lib/libnvpair/Makefile.in | 1 + lib/libspl/Makefile.in | 1 + lib/libspl/asm-generic/Makefile.in | 1 + lib/libspl/asm-i386/Makefile.in | 1 + lib/libspl/asm-x86_64/Makefile.in | 1 + lib/libspl/include/Makefile.in | 1 + lib/libspl/include/ia32/Makefile.in | 1 + lib/libspl/include/ia32/sys/Makefile.in | 1 + lib/libspl/include/rpc/Makefile.in | 1 + lib/libspl/include/sys/Makefile.in | 1 + lib/libspl/include/sys/dktp/Makefile.in | 1 + lib/libspl/include/sys/sysevent/Makefile.in | 1 + lib/libspl/include/util/Makefile.in | 1 + lib/libunicode/Makefile.in | 1 + lib/libuutil/Makefile.in | 1 + lib/libzfs/Makefile.in | 1 + lib/libzpool/Makefile.in | 1 + man/Makefile.in | 1 + man/man8/Makefile.in | 1 + module/zfs/zpl_xattr.c | 8 +- scripts/Makefile.in | 1 + scripts/zpios-profile/Makefile.in | 1 + scripts/zpios-test/Makefile.in | 1 + scripts/zpool-config/Makefile.in | 1 + scripts/zpool-layout/Makefile.in | 1 + zfs_config.h.in | 3 + 52 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 config/kernel-xattr-handler.m4 create mode 100644 include/linux/xattr_compat.h diff --git a/Makefile.in b/Makefile.in index 0d10478d8..f772c3ba4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index 016045a6a..9c56ab45f 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -57,6 +57,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index 08f8377e3..8d215ea47 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index 44fff71f1..4db263271 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index 114128100..6952f9c2b 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index 69747f368..e28058319 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index f800e6bc0..c19f9bc7c 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index 5d32e8106..828621d87 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index ef53493a5..bc9f46581 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index ec16a7394..ead68085f 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -60,6 +60,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 new file mode 100644 index 000000000..fa7294597 --- /dev/null +++ b/config/kernel-xattr-handler.m4 @@ -0,0 +1,32 @@ +dnl # +dnl # 2.6.35 API change, +dnl # The 'struct xattr_handler' was constified in the generic +dnl # super_block structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], + [AC_MSG_CHECKING([whether super_block uses const struct xattr_hander]) + ZFS_LINUX_TRY_COMPILE([ + #include + #include + + const struct xattr_handler xattr_test_handler = { + .prefix = "test", + .get = NULL, + .set = NULL, + }; + + const struct xattr_handler *xattr_handlers[] = { + &xattr_test_handler, + }; + ],[ + struct super_block sb; + + sb.s_xattr = xattr_handlers; + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1, + [super_block uses const struct xattr_hander]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 2c83dc590..d1ed54fba 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -28,6 +28,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_GET_DISK_RO ZFS_AC_KERNEL_RQ_IS_SYNC ZFS_AC_KERNEL_RQ_FOR_EACH_SEGMENT + ZFS_AC_KERNEL_CONST_XATTR_HANDLER if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/configure b/configure index 716a73fee..19123d9be 100755 --- a/configure +++ b/configure @@ -13816,6 +13816,83 @@ $as_echo "no" >&6; } +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether super_block uses const struct xattr_hander" >&5 +$as_echo_n "checking whether super_block uses const struct xattr_hander... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + #include + + const struct xattr_handler xattr_test_handler = { + .prefix = "test", + .get = NULL, + .set = NULL, + }; + + const struct xattr_handler *xattr_handlers[] = { + &xattr_test_handler, + }; + +int +main (void) +{ + + struct super_block sb; + + sb.s_xattr = xattr_handlers; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CONST_XATTR_HANDLER 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + fi rm -Rf build @@ -17343,6 +17420,83 @@ $as_echo "no" >&6; } +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether super_block uses const struct xattr_hander" >&5 +$as_echo_n "checking whether super_block uses const struct xattr_hander... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + #include + + const struct xattr_handler xattr_test_handler = { + .prefix = "test", + .get = NULL, + .set = NULL, + }; + + const struct xattr_handler *xattr_handlers[] = { + &xattr_test_handler, + }; + +int +main (void) +{ + + struct super_block sb; + + sb.s_xattr = xattr_handlers; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CONST_XATTR_HANDLER 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + fi rm -Rf build diff --git a/etc/Makefile.in b/etc/Makefile.in index 4d3939461..b9f7f3685 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/Makefile.in b/include/Makefile.in index f87cd7929..8be6edc8a 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am index 4ccd7b124..67b56f83d 100644 --- a/include/linux/Makefile.am +++ b/include/linux/Makefile.am @@ -2,6 +2,7 @@ COMMON_H = KERNEL_H = \ $(top_srcdir)/include/linux/dcache_compat.h + $(top_srcdir)/include/linux/xattr_compat.h USER_H = diff --git a/include/linux/Makefile.in b/include/linux/Makefile.in index 51d0a6d5b..bd6db6f53 100644 --- a/include/linux/Makefile.in +++ b/include/linux/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ @@ -562,6 +563,7 @@ uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS ps ps-am tags uninstall uninstall-am uninstall-kernelHEADERS \ uninstall-libzfsHEADERS + $(top_srcdir)/include/linux/xattr_compat.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h new file mode 100644 index 000000000..dfa92acab --- /dev/null +++ b/include/linux/xattr_compat.h @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (C) 2011 Lawrence Livermore National Security, LLC. + */ + +#ifndef _ZFS_XATTR_H +#define _ZFS_XATTR_H + +/* + * 2.6.35 API change, + * The const keyword was added to the 'struct xattr_handler' in the + * generic Linux super_block structure. To handle this we define an + * appropriate xattr_handler_t typedef which can be used. This was + * the preferred solution because it keeps the code clean and readable. + */ +#ifdef HAVE_CONST_XATTR_HANDLER +typedef const struct xattr_handler xattr_handler_t; +#else +typedef struct xattr_handler xattr_handler_t; +#endif + +#endif /* _ZFS_XATTR_H */ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 1525d1d07..e95245f7e 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index 4099398b3..fe92c17a0 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index ddad52360..2e78a7645 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index 903b08d37..968a9f27f 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/include/sys/zpl.h b/include/sys/zpl.h index 33f4f621f..b8c3d0985 100644 --- a/include/sys/zpl.h +++ b/include/sys/zpl.h @@ -26,6 +26,7 @@ #define _SYS_ZPL_H #include +#include /* zpl_inode.c */ extern const struct inode_operations zpl_inode_operations; @@ -58,6 +59,6 @@ extern struct file_system_type zpl_fs_type; extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size); extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip); -extern struct xattr_handler *zpl_xattr_handlers[]; +extern xattr_handler_t *zpl_xattr_handlers[]; #endif /* _SYS_ZPL_H */ diff --git a/lib/Makefile.in b/lib/Makefile.in index d607102b1..de0b8b716 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -57,6 +57,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 91590932a..3c249ea7e 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 7839c1354..f162acffe 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index 0bafbab1c..f0da5c4a9 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 8aa947ab4..b21c56dbb 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 0a8ff7c25..7d3048995 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index 6ef74836a..905024274 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index 5c1aeafee..028d19298 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index 0f2a688ae..d72b0aadd 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index d3a8f6fa2..295310bc6 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -57,6 +57,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index 5f7e05fdd..a6f607237 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 850f04542..96fdca680 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index f8f8294d9..8bde0cbd6 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index 19b0f3bcb..ec4a3a9dc 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 96af2d3b1..8d7123566 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index bfaec7a2e..daa1c57c8 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index fb075e8bf..9cb812969 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index 32d6a7404..1cd7310e8 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index 1dbecc335..000f3aa26 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 344612d31..14a2b17cf 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -59,6 +59,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index 3dbed3094..f0b9b705e 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -57,6 +57,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index f3cd85637..58e804b26 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -57,6 +57,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c index 910500a72..86e52f791 100644 --- a/module/zfs/zpl_xattr.c +++ b/module/zfs/zpl_xattr.c @@ -305,7 +305,7 @@ zpl_xattr_user_set(struct inode *ip, const char *name, return (error); } -struct xattr_handler zpl_xattr_user_handler = { +xattr_handler_t zpl_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .get = zpl_xattr_user_get, .set = zpl_xattr_user_set, @@ -351,7 +351,7 @@ zpl_xattr_trusted_set(struct inode *ip, const char *name, return (error); } -struct xattr_handler zpl_xattr_trusted_handler = { +xattr_handler_t zpl_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, .get = zpl_xattr_trusted_get, .set = zpl_xattr_trusted_set, @@ -415,13 +415,13 @@ zpl_xattr_security_init(struct inode *ip, struct inode *dip) return (error); } -struct xattr_handler zpl_xattr_security_handler = { +xattr_handler_t zpl_xattr_security_handler = { .prefix = XATTR_SECURITY_PREFIX, .get = zpl_xattr_security_get, .set = zpl_xattr_security_set, }; -struct xattr_handler *zpl_xattr_handlers[] = { +xattr_handler_t *zpl_xattr_handlers[] = { &zpl_xattr_security_handler, &zpl_xattr_trusted_handler, &zpl_xattr_user_handler, diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 6653bf385..2b2e30d60 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index fd95774cb..f369bbc2c 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index fcb6dfedd..9dfbe107f 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index da8b65e7c..cc3e557e9 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index dde427b3f..881676cdd 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -58,6 +58,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ $(top_srcdir)/config/user-arch.m4 \ $(top_srcdir)/config/user-frame-larger-than.m4 \ diff --git a/zfs_config.h.in b/zfs_config.h.in index f8e218259..52061a039 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -54,6 +54,9 @@ /* blk_rq_sectors() is available */ #undef HAVE_BLK_RQ_SECTORS +/* super_block uses const struct xattr_hander */ +#undef HAVE_CONST_XATTR_HANDLER + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H From 7268e1bec8478639b7a1047e02ab931f30bc2f92 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 11 Feb 2011 08:58:55 -0800 Subject: [PATCH 63/75] Linux 2.6.35 compat, fops->fsync() The fsync() callback in the file_operations structure used to take 3 arguments. The callback now only takes 2 arguments because the dentry argument was determined to be unused by all consumers. To handle this a compatibility prototype was added to ensure the right prototype is used. Our implementation never used the dentry argument either so it's just a matter of using the right prototype. --- Makefile.in | 1 + cmd/Makefile.in | 1 + cmd/zdb/Makefile.in | 1 + cmd/zfs/Makefile.in | 1 + cmd/zinject/Makefile.in | 1 + cmd/zpios/Makefile.in | 1 + cmd/zpool/Makefile.in | 1 + cmd/zpool_id/Makefile.in | 1 + cmd/zpool_layout/Makefile.in | 1 + cmd/ztest/Makefile.in | 1 + config/kernel-fsync.m4 | 20 +++ config/kernel.m4 | 1 + configure | 136 ++++++++++++++++++++ etc/Makefile.in | 1 + include/Makefile.in | 1 + include/linux/Makefile.am | 5 +- include/linux/Makefile.in | 10 +- include/linux/vfs_compat.h | 42 ++++++ include/sys/Makefile.in | 1 + include/sys/fm/Makefile.in | 1 + include/sys/fm/fs/Makefile.in | 1 + include/sys/fs/Makefile.in | 1 + include/sys/zpl.h | 1 + lib/Makefile.in | 1 + lib/libavl/Makefile.in | 1 + lib/libefi/Makefile.in | 1 + lib/libnvpair/Makefile.in | 1 + lib/libspl/Makefile.in | 1 + lib/libspl/asm-generic/Makefile.in | 1 + lib/libspl/asm-i386/Makefile.in | 1 + lib/libspl/asm-x86_64/Makefile.in | 1 + lib/libspl/include/Makefile.in | 1 + lib/libspl/include/ia32/Makefile.in | 1 + lib/libspl/include/ia32/sys/Makefile.in | 1 + lib/libspl/include/rpc/Makefile.in | 1 + lib/libspl/include/sys/Makefile.in | 1 + lib/libspl/include/sys/dktp/Makefile.in | 1 + lib/libspl/include/sys/sysevent/Makefile.in | 1 + lib/libspl/include/util/Makefile.in | 1 + lib/libunicode/Makefile.in | 1 + lib/libuutil/Makefile.in | 1 + lib/libzfs/Makefile.in | 1 + lib/libzpool/Makefile.in | 1 + man/Makefile.in | 1 + man/man8/Makefile.in | 1 + module/zfs/zpl_file.c | 3 +- scripts/Makefile.in | 1 + scripts/zpios-profile/Makefile.in | 1 + scripts/zpios-test/Makefile.in | 1 + scripts/zpool-config/Makefile.in | 1 + scripts/zpool-layout/Makefile.in | 1 + zfs_config.h.in | 3 + 52 files changed, 257 insertions(+), 7 deletions(-) create mode 100644 config/kernel-fsync.m4 create mode 100644 include/linux/vfs_compat.h diff --git a/Makefile.in b/Makefile.in index f772c3ba4..5f3dd16b0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -66,6 +66,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index 9c56ab45f..f90b1a8f2 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index 8d215ea47..f6b7271bb 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index 4db263271..be89bf1b8 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index 6952f9c2b..274f499ab 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index e28058319..2cc033bf6 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index c19f9bc7c..1f33d8082 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index 828621d87..39cb02c20 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index bc9f46581..97844f33f 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index ead68085f..6d0f6f46b 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -54,6 +54,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/config/kernel-fsync.m4 b/config/kernel-fsync.m4 new file mode 100644 index 000000000..2733dba33 --- /dev/null +++ b/config/kernel-fsync.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 2.6.35 API change +dnl # The dentry argument was deamed unused and dropped in 2.6.36. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_FSYNC_2ARGS], [ + AC_MSG_CHECKING([whether fops->fsync() wants 2 args]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*fsync) (struct file *, int datasync) = NULL; + struct file_operations fops; + + fops.fsync = fsync; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_2ARGS_FSYNC, 1, [fops->fsync() want 2 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index d1ed54fba..c411c8f49 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -29,6 +29,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_RQ_IS_SYNC ZFS_AC_KERNEL_RQ_FOR_EACH_SEGMENT ZFS_AC_KERNEL_CONST_XATTR_HANDLER + ZFS_AC_KERNEL_FSYNC_2ARGS if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/configure b/configure index 19123d9be..fa721d43f 100755 --- a/configure +++ b/configure @@ -13900,6 +13900,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether fops->fsync() wants 2 args" >&5 +$as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*fsync) (struct file *, int datasync) = NULL; + struct file_operations fops; + + fops.fsync = fsync; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_2ARGS_FSYNC 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" fi @@ -17504,6 +17572,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether fops->fsync() wants 2 args" >&5 +$as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*fsync) (struct file *, int datasync) = NULL; + struct file_operations fops; + + fops.fsync = fsync; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_2ARGS_FSYNC 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" fi diff --git a/etc/Makefile.in b/etc/Makefile.in index b9f7f3685..b782ffd57 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/Makefile.in b/include/Makefile.in index 8be6edc8a..33e35ab59 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am index 67b56f83d..0ea6cfeda 100644 --- a/include/linux/Makefile.am +++ b/include/linux/Makefile.am @@ -1,8 +1,9 @@ COMMON_H = KERNEL_H = \ - $(top_srcdir)/include/linux/dcache_compat.h - $(top_srcdir)/include/linux/xattr_compat.h + $(top_srcdir)/include/linux/dcache_compat.h \ + $(top_srcdir)/include/linux/xattr_compat.h \ + $(top_srcdir)/include/linux/vfs_compat.h USER_H = diff --git a/include/linux/Makefile.in b/include/linux/Makefile.in index bd6db6f53..cdb09c67e 100644 --- a/include/linux/Makefile.in +++ b/include/linux/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ @@ -85,7 +86,9 @@ am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ SOURCES = DIST_SOURCES = -am__kernel_HEADERS_DIST = $(top_srcdir)/include/linux/dcache_compat.h +am__kernel_HEADERS_DIST = $(top_srcdir)/include/linux/dcache_compat.h \ + $(top_srcdir)/include/linux/xattr_compat.h \ + $(top_srcdir)/include/linux/vfs_compat.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -279,7 +282,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ COMMON_H = KERNEL_H = \ - $(top_srcdir)/include/linux/dcache_compat.h + $(top_srcdir)/include/linux/dcache_compat.h \ + $(top_srcdir)/include/linux/xattr_compat.h \ + $(top_srcdir)/include/linux/vfs_compat.h USER_H = EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H) @@ -563,7 +568,6 @@ uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS ps ps-am tags uninstall uninstall-am uninstall-kernelHEADERS \ uninstall-libzfsHEADERS - $(top_srcdir)/include/linux/xattr_compat.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h new file mode 100644 index 000000000..bbc23a962 --- /dev/null +++ b/include/linux/vfs_compat.h @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (C) 2011 Lawrence Livermore National Security, LLC. + */ + +#ifndef _ZFS_VFS_H +#define _ZFS_VFS_H + +/* + * 2.6.35 API change, + * The dentry argument to the .fsync() vfs hook was deemed unused by + * all filesystem consumers and dropped. Add a compatibility prototype + * to ensure correct usage when defining this callback. + */ +#ifdef HAVE_2ARGS_FSYNC +#define ZPL_FSYNC_PROTO(fn, x, y, z) static int fn(struct file *x, int z) +#else +#define ZPL_FSYNC_PROTO(fn, x, y, z) static int fn(struct file *x, \ + struct dentry *y, int z) +#endif + +#endif /* _ZFS_VFS_H */ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index e95245f7e..71b4cb3c4 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index fe92c17a0..e94bc0215 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index 2e78a7645..8ae7708ea 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index 968a9f27f..000f6ef42 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/include/sys/zpl.h b/include/sys/zpl.h index b8c3d0985..b6da0d271 100644 --- a/include/sys/zpl.h +++ b/include/sys/zpl.h @@ -26,6 +26,7 @@ #define _SYS_ZPL_H #include +#include #include /* zpl_inode.c */ diff --git a/lib/Makefile.in b/lib/Makefile.in index de0b8b716..123beb673 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 3c249ea7e..bdd51988f 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index f162acffe..487692f29 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index f0da5c4a9..eed77dc48 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index b21c56dbb..74aa1d261 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 7d3048995..0a422cfb9 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index 905024274..8f57a054b 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index 028d19298..6a7e2bde0 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index d72b0aadd..a50ff33ce 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index 295310bc6..82b4cb514 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index a6f607237..5669f8519 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 96fdca680..7902f5093 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index 8bde0cbd6..1f96a1ee1 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index ec4a3a9dc..c670d35ab 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 8d7123566..5724382b0 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index daa1c57c8..e7b4f91dd 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index 9cb812969..c200a8589 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index 1cd7310e8..a41d12d5b 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index 000f3aa26..b92f2b28e 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 14a2b17cf..0f685471a 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index f0b9b705e..93475646b 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index 58e804b26..a0b8a5638 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index 585f971e8..ed6704bb2 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -45,8 +45,7 @@ zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) return (error); } -static int -zpl_fsync(struct file *filp, struct dentry *dentry, int datasync) +ZPL_FSYNC_PROTO(zpl_fsync, filp, unused_dentry, datasync) { cred_t *cr; int error; diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 2b2e30d60..ba9ab4ed7 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index f369bbc2c..6e278eadb 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index 9dfbe107f..5a96a4d8d 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index cc3e557e9..c3882fda6 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index 881676cdd..44dd41e04 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ diff --git a/zfs_config.h.in b/zfs_config.h.in index 52061a039..fd7bd668c 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -6,6 +6,9 @@ /* bio_end_io_t wants 2 args */ #undef HAVE_2ARGS_BIO_END_IO_T +/* fops->fsync() want 2 args */ +#undef HAVE_2ARGS_FSYNC + /* struct block_device_operations use bdevs */ #undef HAVE_BDEV_BLOCK_DEVICE_OPERATIONS From f9637c6c8b9c452c440a366aa937b363f027d95e Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 11 Feb 2011 10:33:01 -0800 Subject: [PATCH 64/75] Linux 2.6.33 compat, get/set xattr callbacks The xattr handler prototypes were sanitized with the idea being that the same handlers could be used for multiple methods. The result of this was the inode type was changes to a dentry, and both the get() and set() hooks had a handler_flags argument added. The list() callback was similiarly effected but no autoconf check was added because we do not use the list() callback. --- config/kernel-xattr-handler.m4 | 49 ++++++ config/kernel.m4 | 2 + configure | 278 +++++++++++++++++++++++++++++++++ include/linux/xattr_compat.h | 45 ++++++ module/zfs/zpl_xattr.c | 20 ++- zfs_config.h.in | 6 + 6 files changed, 393 insertions(+), 7 deletions(-) diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 index fa7294597..1ebe1f0d9 100644 --- a/config/kernel-xattr-handler.m4 +++ b/config/kernel-xattr-handler.m4 @@ -30,3 +30,52 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], AC_MSG_RESULT([no]) ]) ]) + +dnl # +dnl # 2.6.33 API change, +dnl # The xattr_hander->get() callback was changed to take a dentry +dnl # instead of an inode, and a handler_flags argument was added. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [ + AC_MSG_CHECKING([whether xattr_handler->get() wants dentry]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DENTRY_XATTR_GET, 1, + [xattr_handler->get() wants dentry]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.33 API change, +dnl # The xattr_hander->set() callback was changed to take a dentry +dnl # instead of an inode, and a handler_flags argument was added. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [ + AC_MSG_CHECKING([whether xattr_handler->set() wants dentry]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DENTRY_XATTR_SET, 1, + [xattr_handler->set() wants dentry]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index c411c8f49..1f271d178 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -29,6 +29,8 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_RQ_IS_SYNC ZFS_AC_KERNEL_RQ_FOR_EACH_SEGMENT ZFS_AC_KERNEL_CONST_XATTR_HANDLER + ZFS_AC_KERNEL_XATTR_HANDLER_GET + ZFS_AC_KERNEL_XATTR_HANDLER_SET ZFS_AC_KERNEL_FSYNC_2ARGS if test "$LINUX_OBJ" != "$LINUX"; then diff --git a/configure b/configure index fa721d43f..55cf1576f 100755 --- a/configure +++ b/configure @@ -13900,6 +13900,145 @@ fi + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->get() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DENTRY_XATTR_GET 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->set() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DENTRY_XATTR_SET 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether fops->fsync() wants 2 args" >&5 $as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } @@ -17572,6 +17711,145 @@ fi + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->get() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DENTRY_XATTR_GET 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->set() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DENTRY_XATTR_SET 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether fops->fsync() wants 2 args" >&5 $as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h index dfa92acab..9878aab72 100644 --- a/include/linux/xattr_compat.h +++ b/include/linux/xattr_compat.h @@ -39,4 +39,49 @@ typedef const struct xattr_handler xattr_handler_t; typedef struct xattr_handler xattr_handler_t; #endif +/* + * 2.6.33 API change, + * The xattr_hander->get() callback was changed to take a dentry + * instead of an inode, and a handler_flags argument was added. + */ +#ifdef HAVE_DENTRY_XATTR_GET +#define ZPL_XATTR_GET_WRAPPER(fn) \ +static int \ +fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \ + int unused_handler_flags) \ +{ \ + return __ ## fn(dentry->d_inode, name, buffer, size); \ +} +#else +#define ZPL_XATTR_GET_WRAPPER(fn) \ +static int \ +fn(struct inode *ip, const char *name, void *buffer, size_t size) \ +{ \ + return __ ## fn(ip, name, buffer, size); \ +} +#endif /* HAVE_DENTRY_XATTR_GET */ + +/* + * 2.6.33 API change, + * The xattr_hander->set() callback was changed to take a dentry + * instead of an inode, and a handler_flags argument was added. + */ +#ifdef HAVE_DENTRY_XATTR_SET +#define ZPL_XATTR_SET_WRAPPER(fn) \ +static int \ +fn(struct dentry *dentry, const char *name, const void *buffer, \ + size_t size, int flags, int unused_handler_flags) \ +{ \ + return __ ## fn(dentry->d_inode, name, buffer, size, flags); \ +} +#else +#define ZPL_XATTR_SET_WRAPPER(fn) \ +static int \ +fn(struct inode *ip, const char *name, const void *buffer, \ + size_t size, int flags) \ +{ \ + return __ ## fn(ip, name, buffer, size, flags); \ +} +#endif /* HAVE_DENTRY_XATTR_SET */ + #endif /* _ZFS_XATTR_H */ diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c index 86e52f791..7a1ecec8f 100644 --- a/module/zfs/zpl_xattr.c +++ b/module/zfs/zpl_xattr.c @@ -266,7 +266,7 @@ out: } static int -zpl_xattr_user_get(struct inode *ip, const char *name, +__zpl_xattr_user_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -284,9 +284,10 @@ zpl_xattr_user_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get); static int -zpl_xattr_user_set(struct inode *ip, const char *name, +__zpl_xattr_user_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -304,6 +305,7 @@ zpl_xattr_user_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_user_set); xattr_handler_t zpl_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, @@ -312,7 +314,7 @@ xattr_handler_t zpl_xattr_user_handler = { }; static int -zpl_xattr_trusted_get(struct inode *ip, const char *name, +__zpl_xattr_trusted_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -330,9 +332,10 @@ zpl_xattr_trusted_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get); static int -zpl_xattr_trusted_set(struct inode *ip, const char *name, +__zpl_xattr_trusted_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -350,6 +353,7 @@ zpl_xattr_trusted_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_trusted_set); xattr_handler_t zpl_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, @@ -358,7 +362,7 @@ xattr_handler_t zpl_xattr_trusted_handler = { }; static int -zpl_xattr_security_get(struct inode *ip, const char *name, +__zpl_xattr_security_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -373,9 +377,10 @@ zpl_xattr_security_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get); static int -zpl_xattr_security_set(struct inode *ip, const char *name, +__zpl_xattr_security_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -390,6 +395,7 @@ zpl_xattr_security_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set); int zpl_xattr_security_init(struct inode *ip, struct inode *dip) @@ -407,7 +413,7 @@ zpl_xattr_security_init(struct inode *ip, struct inode *dip) return (error); } - error = zpl_xattr_security_set(ip, name, value, len, 0); + error = __zpl_xattr_security_set(ip, name, value, len, 0); kfree(name); kfree(value); diff --git a/zfs_config.h.in b/zfs_config.h.in index fd7bd668c..d6999bbda 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -60,6 +60,12 @@ /* super_block uses const struct xattr_hander */ #undef HAVE_CONST_XATTR_HANDLER +/* xattr_handler->get() wants dentry */ +#undef HAVE_DENTRY_XATTR_GET + +/* xattr_handler->set() wants dentry */ +#undef HAVE_DENTRY_XATTR_SET + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H From 2c395def2763ccc7a549d297f7f11bd304caaeae Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 11 Feb 2011 13:46:10 -0800 Subject: [PATCH 65/75] Linux 2.6.36 compat, sops->evict_inode() The new prefered inteface for evicting an inode from the inode cache is the ->evict_inode() callback. It replaces both the ->delete_inode() and ->clear_inode() callbacks which were previously used for this. --- Makefile.in | 1 + cmd/Makefile.in | 1 + cmd/zdb/Makefile.in | 1 + cmd/zfs/Makefile.in | 1 + cmd/zinject/Makefile.in | 1 + cmd/zpios/Makefile.in | 1 + cmd/zpool/Makefile.in | 1 + cmd/zpool_id/Makefile.in | 1 + cmd/zpool_layout/Makefile.in | 1 + cmd/ztest/Makefile.in | 1 + config/kernel-evict-inode.m4 | 21 +++ config/kernel.m4 | 1 + configure | 136 ++++++++++++++++++++ etc/Makefile.in | 1 + include/Makefile.in | 1 + include/linux/Makefile.in | 1 + include/sys/Makefile.in | 1 + include/sys/fm/Makefile.in | 1 + include/sys/fm/fs/Makefile.in | 1 + include/sys/fs/Makefile.in | 1 + lib/Makefile.in | 1 + lib/libavl/Makefile.in | 1 + lib/libefi/Makefile.in | 1 + lib/libnvpair/Makefile.in | 1 + lib/libspl/Makefile.in | 1 + lib/libspl/asm-generic/Makefile.in | 1 + lib/libspl/asm-i386/Makefile.in | 1 + lib/libspl/asm-x86_64/Makefile.in | 1 + lib/libspl/include/Makefile.in | 1 + lib/libspl/include/ia32/Makefile.in | 1 + lib/libspl/include/ia32/sys/Makefile.in | 1 + lib/libspl/include/rpc/Makefile.in | 1 + lib/libspl/include/sys/Makefile.in | 1 + lib/libspl/include/sys/dktp/Makefile.in | 1 + lib/libspl/include/sys/sysevent/Makefile.in | 1 + lib/libspl/include/util/Makefile.in | 1 + lib/libunicode/Makefile.in | 1 + lib/libuutil/Makefile.in | 1 + lib/libzfs/Makefile.in | 1 + lib/libzpool/Makefile.in | 1 + man/Makefile.in | 1 + man/man8/Makefile.in | 1 + module/zfs/zfs_vnops.c | 2 - module/zfs/zpl_super.c | 60 +++++++-- scripts/Makefile.in | 1 + scripts/zpios-profile/Makefile.in | 1 + scripts/zpios-test/Makefile.in | 1 + scripts/zpool-config/Makefile.in | 1 + scripts/zpool-layout/Makefile.in | 1 + zfs_config.h.in | 3 + 50 files changed, 253 insertions(+), 14 deletions(-) create mode 100644 config/kernel-evict-inode.m4 diff --git a/Makefile.in b/Makefile.in index 5f3dd16b0..3c266e161 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65,6 +65,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index f90b1a8f2..05e70be6b 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -50,6 +50,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index f6b7271bb..0ff5b4bc5 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index be89bf1b8..d6ce3ae34 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index 274f499ab..8182ab346 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index 2cc033bf6..b29bfd7d6 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index 1f33d8082..9ceb47448 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index 39cb02c20..c518542ce 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index 97844f33f..6b21c3e40 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index 6d0f6f46b..c7291cb36 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/config/kernel-evict-inode.m4 b/config/kernel-evict-inode.m4 new file mode 100644 index 000000000..3cf5a3666 --- /dev/null +++ b/config/kernel-evict-inode.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 2.6.36 API change +dnl # The sops->delete_inode() and sops->clear_inode() callbacks have +dnl # replaced by a single sops->evict_inode() callback. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [ + AC_MSG_CHECKING([whether sops->evict_inode() exists]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + void (*evict_inode) (struct inode *) = NULL; + struct super_operations sops; + + sops.evict_inode = evict_inode; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_EVICT_INODE, 1, [sops->evict_inode() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 1f271d178..c3321ed8d 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -32,6 +32,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_XATTR_HANDLER_GET ZFS_AC_KERNEL_XATTR_HANDLER_SET ZFS_AC_KERNEL_FSYNC_2ARGS + ZFS_AC_KERNEL_EVICT_INODE if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/configure b/configure index 55cf1576f..02a071557 100755 --- a/configure +++ b/configure @@ -14107,6 +14107,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether sops->evict_inode() exists" >&5 +$as_echo_n "checking whether sops->evict_inode() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + void (*evict_inode) (struct inode *) = NULL; + struct super_operations sops; + + sops.evict_inode = evict_inode; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_EVICT_INODE 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" fi @@ -17918,6 +17986,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether sops->evict_inode() exists" >&5 +$as_echo_n "checking whether sops->evict_inode() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + void (*evict_inode) (struct inode *) = NULL; + struct super_operations sops; + + sops.evict_inode = evict_inode; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_EVICT_INODE 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + if test "$LINUX_OBJ" != "$LINUX"; then KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" fi diff --git a/etc/Makefile.in b/etc/Makefile.in index b782ffd57..88640a716 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/Makefile.in b/include/Makefile.in index 33e35ab59..f47e747f1 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/linux/Makefile.in b/include/linux/Makefile.in index cdb09c67e..e70c16afc 100644 --- a/include/linux/Makefile.in +++ b/include/linux/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 71b4cb3c4..37339e255 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index e94bc0215..d05018dd1 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index 8ae7708ea..e2ad9533f 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index 000f6ef42..ce196fb89 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 123beb673..139d3e436 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -50,6 +50,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index bdd51988f..421b2851f 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 487692f29..00f109db1 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index eed77dc48..c47aa7d89 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 74aa1d261..be5ddf1ec 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 0a422cfb9..67e9a0f44 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index 8f57a054b..bbb7265ee 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index 6a7e2bde0..625adc54e 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index a50ff33ce..66ba65f70 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index 82b4cb514..c0836280a 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -50,6 +50,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index 5669f8519..243eaeb12 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 7902f5093..35c2b1403 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index 1f96a1ee1..b0b29bf2a 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index c670d35ab..f98455474 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 5724382b0..d787d8a8b 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index e7b4f91dd..f3950b9b1 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index c200a8589..64bfe3990 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index a41d12d5b..6b0525ea6 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index b92f2b28e..e10cd8078 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 0f685471a..96bced0bf 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -52,6 +52,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index 93475646b..c209c2961 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -50,6 +50,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index a0b8a5638..0a8d52923 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -50,6 +50,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 30b30891b..363307932 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -3632,8 +3632,6 @@ zfs_inactive(struct inode *ip) zfs_sb_t *zsb = ITOZSB(ip); int error; - truncate_inode_pages(&ip->i_data, 0); - #ifdef HAVE_SNAPSHOT /* Early return for snapshot inode? */ #endif /* HAVE_SNAPSHOT */ diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index bbb7beaf3..0417ce2ff 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -47,22 +47,54 @@ zpl_inode_destroy(struct inode *ip) zfs_inode_destroy(ip); } -static void -zpl_inode_delete(struct inode *ip) -{ - loff_t oldsize = i_size_read(ip); - - i_size_write(ip, 0); - truncate_pagecache(ip, oldsize, 0); - clear_inode(ip); -} - +/* + * When ->drop_inode() is called its return value indicates if the + * inode should be evicted from the inode cache. If the inode is + * unhashed and has no links the default policy is to evict it + * immediately. + * + * Prior to 2.6.36 this eviction was accomplished by the vfs calling + * ->delete_inode(). It was ->delete_inode()'s responsibility to + * truncate the inode pages and call clear_inode(). The call to + * clear_inode() synchronously invalidates all the buffers and + * calls ->clear_inode(). It was ->clear_inode()'s responsibility + * to cleanup and filesystem specific data before freeing the inode. + * + * This elaborate mechanism was replaced by ->evict_inode() which + * does the job of both ->delete_inode() and ->clear_inode(). It + * will be called exactly once, and when it returns the inode must + * be in a state where it can simply be freed. The ->evict_inode() + * callback must minimally truncate the inode pages, and call + * end_writeback() to complete all outstanding writeback for the + * inode. After this is complete evict inode can cleanup any + * remaining filesystem specific data. + */ +#ifdef HAVE_EVICT_INODE static void zpl_evict_inode(struct inode *ip) { + truncate_inode_pages(&ip->i_data, 0); + end_writeback(ip); zfs_inactive(ip); } +#else + +static void +zpl_clear_inode(struct inode *ip) +{ + zfs_inactive(ip); +} + +static void +zpl_inode_delete(struct inode *ip) +{ + truncate_inode_pages(&ip->i_data, 0); + clear_inode(ip); +} + +#endif /* HAVE_EVICT_INODE */ + static void zpl_put_super(struct super_block *sb) { @@ -136,11 +168,15 @@ zpl_kill_sb(struct super_block *sb) const struct super_operations zpl_super_operations = { .alloc_inode = zpl_inode_alloc, .destroy_inode = zpl_inode_destroy, - .delete_inode = zpl_inode_delete, .dirty_inode = NULL, .write_inode = NULL, .drop_inode = NULL, - .clear_inode = zpl_evict_inode, +#ifdef HAVE_EVICT_INODE + .evict_inode = zpl_evict_inode, +#else + .clear_inode = zpl_clear_inode, + .delete_inode = zpl_inode_delete, +#endif /* HAVE_EVICT_INODE */ .put_super = zpl_put_super, .write_super = NULL, .sync_fs = NULL, diff --git a/scripts/Makefile.in b/scripts/Makefile.in index ba9ab4ed7..ba491bc54 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index 6e278eadb..bd356296e 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index 5a96a4d8d..0030fa3d1 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index c3882fda6..5fd446dc6 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index 44dd41e04..d8b181d9f 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -51,6 +51,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ $(top_srcdir)/config/kernel-fmode-t.m4 \ $(top_srcdir)/config/kernel-fsync.m4 \ $(top_srcdir)/config/kernel-get-disk-ro.m4 \ diff --git a/zfs_config.h.in b/zfs_config.h.in index d6999bbda..2f09157e3 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -69,6 +69,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* sops->evict_inode() exists */ +#undef HAVE_EVICT_INODE + /* kernel defines fmode_t */ #undef HAVE_FMODE_T From d5674448094cec6eb3563afb63cc1e096bc5b280 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 09:40:29 -0800 Subject: [PATCH 66/75] Create minors for all zvols It was noticed that when you have zvols in multiple datasets not all of the zvol devices are created at module load time. Fajarnugraha did the leg work to identify that the root cause of this bug is a non-zero return value from zvol_create_minors_cb(). Returning a non-zero value from the dmu_objset_find_spa() callback function results in aborting processing the remaining children in a dataset. Since we want to ensure that the callback in run on all children regardless of error simply unconditionally return zero from the zvol_create_minors_cb(). This callback function is solely used for this purpose so surpressing the error is safe. Closes #96 --- module/zfs/zvol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 3d829a3d4..04c885f68 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1230,7 +1230,8 @@ zvol_create_minors_cb(spa_t *spa, uint64_t dsobj, if (strchr(dsname, '/') == NULL) return 0; - return __zvol_create_minor(dsname); + (void) __zvol_create_minor(dsname); + return (0); } /* From d8fd10545b677cb4b770674372c1e116b7c22c64 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 09:51:44 -0800 Subject: [PATCH 67/75] Fix FIFO and socket handling Under Linux when creating a fifo or socket type device in the ZFS filesystem it's critical that the rdev is stored in a SA. This was already being correctly done for character and block devices, but that logic needed to be extended to include FIFOs and sockets. This patch takes care of device creation but a follow on patch may still be required to verify that the dev_t is being correctly packed/unpacked from the SA. --- module/zfs/zfs_znode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 024668287..56ac2ab8c 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -586,7 +586,8 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, size = links = 0; } - if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode)) + if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode) || + S_ISFIFO(vap->va_mode) || S_ISSOCK(vap->va_mode)) rdev = zfs_expldev(vap->va_rdev); parent = dzp->z_id; @@ -677,10 +678,10 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, &empty_xattr, 8); } if (obj_type == DMU_OT_ZNODE || - (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))) { + (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode) || + S_ISFIFO(vap->va_mode) || S_ISSOCK(vap->va_mode))) { SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zsb), NULL, &rdev, 8); - } if (obj_type == DMU_OT_ZNODE) { SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zsb), From a6695d83b763aaeeeeb6d4bdb57ed59a384106f7 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 09:55:53 -0800 Subject: [PATCH 68/75] Add get/setattr, get/setxattr hooks While the attr/xattr hooks were already in place for regular files this hooks can also apply to directories and special files. While they aren't typically used in this way, it should be supported. This patch registers these additional callbacks for both directory and special inode types. --- module/zfs/zpl_inode.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index e866dcd4d..637a7dc69 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -288,7 +288,6 @@ out: } const struct inode_operations zpl_inode_operations = { - .check_acl = NULL, .create = zpl_create, .link = zpl_link, .unlink = zpl_unlink, @@ -306,7 +305,6 @@ const struct inode_operations zpl_inode_operations = { }; const struct inode_operations zpl_dir_inode_operations = { - .check_acl = NULL, .create = zpl_create, .lookup = zpl_lookup, .link = zpl_link, @@ -317,15 +315,24 @@ const struct inode_operations zpl_dir_inode_operations = { .mknod = zpl_mknod, .rename = zpl_rename, .setattr = zpl_setattr, + .getattr = zpl_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = zpl_xattr_list, }; const struct inode_operations zpl_symlink_inode_operations = { - .check_acl = NULL, .readlink = generic_readlink, .follow_link = zpl_follow_link, .put_link = zpl_put_link, }; const struct inode_operations zpl_special_inode_operations = { - .check_acl = NULL, + .setattr = zpl_setattr, + .getattr = zpl_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = zpl_xattr_list, }; From 07bd86718b74b2d8e0f633f1b80e976892eaf329 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 11:05:55 -0800 Subject: [PATCH 69/75] Suppress share error on mount Until code is added to support automatically sharing datasets we should return success instead of failure. This prevents the command line tools from returning a non-zero error code. While a user likely won't notice this, test scripts like zconfig.sh do and correctly fail because of it. --- lib/libzfs/libzfs_mount.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index f55b16bdc..f8f12d1bf 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -797,8 +797,9 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) dgettext(TEXT_DOMAIN, "cannot share '%s': %s"), zfs_get_name(zhp), _sa_errorstr != NULL ? _sa_errorstr(ret) : ""); -#endif /* HAVE_SHARE */ return (-1); +#endif /* HAVE_SHARE */ + return (0); } for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { From b9f6a49025809d658754c758dc7e2a81ee41271b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 11:10:31 -0800 Subject: [PATCH 70/75] Update 'zfs.sh -u' to umount all zfs filesystems Before it is safe to unload the zfs module stack all mounted zfs filesystems must be unmounted. If they are not unmounted, there will be references held on the modules and the stack cannot be removed. To handle this have 'zfs.sh -u' which is used by all of the test scripts umount all zfs filesystem before attempting to unload the module stack. --- scripts/zfs.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/zfs.sh b/scripts/zfs.sh index 6060fbaa8..4a707fabf 100755 --- a/scripts/zfs.sh +++ b/scripts/zfs.sh @@ -65,6 +65,7 @@ if [ $(id -u) != 0 ]; then fi if [ ${UNLOAD} ]; then + umount -t zfs -a unload_modules else check_modules || die "${ERROR}" From 8b4f9a2d55fc5ee28f69b29f2fece7d8e2cb5c7a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Feb 2011 15:54:55 -0800 Subject: [PATCH 71/75] Fix readlink(2) This patch addresses three issues related to symlinks. 1) Revert the zfs_follow_link() function to a modified version of the original zfs_readlink(). The only changes from the original OpenSolaris version relate to using Linux types. For the moment this means no vnode's and no zfsvfs_t. The caller zpl_follow_link() was also updated accordingly. This change was reverted because it was slightly gratuitious. 2) Update zpl_follow_link() to use local variables for the link buffer. I'd forgotten that iov.iov_base is updated by uiomove() so after the call to zfs_readlink() it can not longer be used. We need our own private copy of the link pointer. 3) Allocate MAXPATHLEN instead of MAXPATHLEN+1. By default MAXPATHLEN is 4096 bytes which is a full page, adding one to it pushes it slightly over a page. That means you'll likely end up allocating 2 pages which is wasteful of memory and possibly slightly slower. --- module/zfs/zfs_vnops.c | 33 ++++++++------------------------- module/zfs/zpl_inode.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 363307932..8bff0ef4b 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -3183,8 +3183,9 @@ EXPORT_SYMBOL(zfs_symlink); * Return, in the buffer contained in the provided uio structure, * the symbolic path referred to by ip. * - * IN: dentry - dentry of symbolic link. - * nd - namedata for symlink + * IN: ip - inode of symbolic link + * uio - structure to contain the link path. + * cr - credentials of caller. * * RETURN: 0 if success * error code if failure @@ -3194,47 +3195,29 @@ EXPORT_SYMBOL(zfs_symlink); */ /* ARGSUSED */ int -zfs_follow_link(struct dentry *dentry, struct nameidata *nd) +zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr) { - struct inode *ip = dentry->d_inode; znode_t *zp = ITOZ(ip); zfs_sb_t *zsb = ITOZSB(ip); - struct iovec iov; - uio_t uio; int error; ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); - iov.iov_len = MAXPATHLEN + 1; - iov.iov_base = kmem_zalloc(iov.iov_len, KM_SLEEP); - - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = iov.iov_len; - uio.uio_segflg = UIO_SYSSPACE; - mutex_enter(&zp->z_lock); if (zp->z_is_sa) - error = sa_lookup_uio(zp->z_sa_hdl, SA_ZPL_SYMLINK(zsb), &uio); + error = sa_lookup_uio(zp->z_sa_hdl, + SA_ZPL_SYMLINK(zsb), uio); else - error = zfs_sa_readlink(zp, &uio); + error = zfs_sa_readlink(zp, uio); mutex_exit(&zp->z_lock); ZFS_ACCESSTIME_STAMP(zsb, zp); zfs_inode_update(zp); - - if (error) { - kmem_free(iov.iov_base, iov.iov_len); - nd_set_link(nd, ERR_PTR(error)); - } else { - nd_set_link(nd, iov.iov_base); - } - ZFS_EXIT(zsb); return (error); } -EXPORT_SYMBOL(zfs_follow_link); +EXPORT_SYMBOL(zfs_readlink); /* * Insert a new entry into directory tdip referencing sip. diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 637a7dc69..75d299b47 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -245,8 +245,33 @@ out: static void * zpl_follow_link(struct dentry *dentry, struct nameidata *nd) { - (void) zfs_follow_link(dentry, nd); - return NULL; + struct inode *ip = dentry->d_inode; + struct iovec iov; + uio_t uio; + char *link; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + + iov.iov_len = MAXPATHLEN; + iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP); + + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = (MAXPATHLEN - 1); + uio.uio_segflg = UIO_SYSSPACE; + + error = zfs_readlink(ip, &uio, cr); + if (error) { + kmem_free(link, MAXPATHLEN); + nd_set_link(nd, ERR_PTR(error)); + } else { + nd_set_link(nd, link); + } + + put_cred(cr); + return (NULL); } static void @@ -256,7 +281,7 @@ zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) link = nd_get_link(nd); if (!IS_ERR(link)) - kmem_free(link, MAXPATHLEN + 1); + kmem_free(link, MAXPATHLEN); } static int From f03e41e8da6d184039ea3b03ba4937f4786a3f22 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 17 Feb 2011 09:21:39 -0800 Subject: [PATCH 72/75] Improve 'zpool import' safety There are three improvements here to 'zpool import' proposed by Fajar in Github issue #98. They are all good so I'm commiting all three. 1) Add descriptions for "hpet" and "core" blacklist entries. 2) Add "core" to the blacklist, as described in the issue accessing this device will crash Xen dom0. 3) Refine probing behavior to use fstatat64(). This allows us to determine if a device is a block device or a regular file without having to open it. This is the safest appraoch when probing /dev/ because the simple act of opening a device may have unexpected consequences. Closes #98 --- lib/libzfs/libzfs_import.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c index 8668583b2..7048a52c9 100644 --- a/lib/libzfs/libzfs_import.c +++ b/lib/libzfs/libzfs_import.c @@ -1078,6 +1078,10 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) * parport* - Parallel port interface. * lp* - Printer interface. * fd* - Floppy interface. + * hpet - High Precision Event Timer, crashes qemu + * when accessed from a virtual machine. + * core - Symlink to /proc/kcore, causes a crash + * when access from Xen dom0. */ if ((strncmp(name, "watchdog", 8) == 0) || (strncmp(name, "fuse", 4) == 0) || @@ -1087,22 +1091,21 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) (strncmp(name, "parport", 7) == 0) || (strncmp(name, "lp", 2) == 0) || (strncmp(name, "fd", 2) == 0) || - (strncmp(name, "hpet", 4) == 0)) - continue; - - if ((fd = openat64(dfd, name, O_RDONLY)) < 0) + (strncmp(name, "hpet", 4) == 0) || + (strncmp(name, "core", 4) == 0)) continue; /* * Ignore failed stats. We only want regular - * files and block devs. + * files and block devices. */ - if (fstat64(fd, &statbuf) != 0 || + if ((fstatat64(dfd, name, &statbuf, 0) != 0) || (!S_ISREG(statbuf.st_mode) && - !S_ISBLK(statbuf.st_mode))) { - (void) close(fd); + !S_ISBLK(statbuf.st_mode))) + continue; + + if ((fd = openat64(dfd, name, O_RDONLY)) < 0) continue; - } if ((zpool_read_label(fd, &config)) != 0) { (void) close(fd); From 5095000169f695ea6b65d74da917c3f465d05aab Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 17 Feb 2011 09:48:06 -0800 Subject: [PATCH 73/75] Use -zfs_readlink() error The zfs_readlink() function returns a Solaris positive error value and that needs to be converted to a Linux negative error value. While in this case nothing would actually go wrong, it's still incorrect and should be fixed if for no other reason than clarity. --- module/zfs/zpl_inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 75d299b47..888dc17cc 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -262,7 +262,7 @@ zpl_follow_link(struct dentry *dentry, struct nameidata *nd) uio.uio_resid = (MAXPATHLEN - 1); uio.uio_segflg = UIO_SYSSPACE; - error = zfs_readlink(ip, &uio, cr); + error = -zfs_readlink(ip, &uio, cr); if (error) { kmem_free(link, MAXPATHLEN); nd_set_link(nd, ERR_PTR(error)); From efd1832bc615a4e32259e31d1c7ff0af14f5c1b2 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 17 Feb 2011 11:26:51 -0800 Subject: [PATCH 74/75] Fix symlink(2) inode reference count Under Linux sys_symlink(2) should result in a inode being created with one reference for the inode itself, and a second reference on the inode which is held by the new dentry. Under Solaris this appears not to be the case. Their zfs_symlink() handler drops the inode reference before returning. The result of this under Linux is that the reference count for symlinks is always one smaller than it should have been. This results in a BUG() when the symlink is unlinked. To handle this the Linux port now keeps the inode reference which differs from the Solaris behavior. This results in correct reference counts. Closes #96 --- module/zfs/zfs_vnops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 8bff0ef4b..fcc85b8a0 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -3169,7 +3169,6 @@ top: zfs_dirent_unlock(dl); *ipp = ZTOI(zp); - iput(ZTOI(zp)); if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); From 037849f854c511d86e3564ed7000e6c6472d6f70 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 17 Feb 2011 14:17:44 -0800 Subject: [PATCH 75/75] Use provided uid/gid for setattr When changing the uid/gid of a file via zfs_setattr() use the Posix id passed in iattr->ia_uid/gid. While the zfs_fuid_create() code already had the fuid support disabled for Linux it was returning the uid/gid from the credential. With this change the 'chown' command which relies on setxattr is now working properly. Also remove a little stray white space which was in front of zfs_update_inode() call and the end of zfs_setattr(). --- module/zfs/zfs_fuid.c | 8 ++++---- module/zfs/zfs_vnops.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index f1e071fc7..ca03373c7 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -639,10 +639,10 @@ zfs_fuid_create(zfs_sb_t *zsb, uint64_t id, cred_t *cr, } return (FUID_ENCODE(idx, rid)); #else - if (type == ZFS_OWNER) - return crgetuid(cr); - else - return crgetgid(cr); + /* + * The Linux port only supports POSIX IDs, use the passed id. + */ + return (id); #endif } diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index fcc85b8a0..b20e3b2c3 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -2575,7 +2575,7 @@ out: } else { err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); dmu_tx_commit(tx); - zfs_inode_update(zp); + zfs_inode_update(zp); } out2: