1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5ea8dc4b6Seschrock * Common Development and Distribution License (the "License"). 6ea8dc4b6Seschrock * You may not use this file except in compliance with the License. 7fa9e4066Sahrens * 8fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 10fa9e4066Sahrens * See the License for the specific language governing permissions 11fa9e4066Sahrens * and limitations under the License. 12fa9e4066Sahrens * 13fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e4066Sahrens * 19fa9e4066Sahrens * CDDL HEADER END 20fa9e4066Sahrens */ 21fa9e4066Sahrens /* 228f2529deSMark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 234bb73804SMatthew Ahrens * Copyright (c) 2012, 2014 by Delphix. All rights reserved. 24c3d26abcSMatthew Ahrens * Copyright (c) 2014 Integros [integros.com] 25fa9e4066Sahrens */ 26fa9e4066Sahrens 2775c76197Speteh /* Portions Copyright 2007 Jeremy Teo */ 2875c76197Speteh 2955434c77Sek110237 #ifdef _KERNEL 30fa9e4066Sahrens #include <sys/types.h> 31fa9e4066Sahrens #include <sys/param.h> 32fa9e4066Sahrens #include <sys/time.h> 33fa9e4066Sahrens #include <sys/systm.h> 34fa9e4066Sahrens #include <sys/sysmacros.h> 35fa9e4066Sahrens #include <sys/resource.h> 36fa9e4066Sahrens #include <sys/mntent.h> 3772fc53bcSmarks #include <sys/mkdev.h> 38de8267e0Stimh #include <sys/u8_textprep.h> 39ab04eb8eStimh #include <sys/dsl_dataset.h> 40fa9e4066Sahrens #include <sys/vfs.h> 41aa59c4cbSrsb #include <sys/vfs_opreg.h> 42fa9e4066Sahrens #include <sys/vnode.h> 43fa9e4066Sahrens #include <sys/file.h> 44fa9e4066Sahrens #include <sys/kmem.h> 45fa9e4066Sahrens #include <sys/errno.h> 46fa9e4066Sahrens #include <sys/unistd.h> 47fa9e4066Sahrens #include <sys/mode.h> 48fa9e4066Sahrens #include <sys/atomic.h> 49fa9e4066Sahrens #include <vm/pvn.h> 50fa9e4066Sahrens #include "fs/fs_subr.h" 51fa9e4066Sahrens #include <sys/zfs_dir.h> 52fa9e4066Sahrens #include <sys/zfs_acl.h> 53fa9e4066Sahrens #include <sys/zfs_ioctl.h> 54104e2ed7Sperrin #include <sys/zfs_rlock.h> 55da6c28aaSamw #include <sys/zfs_fuid.h> 560a586ceaSMark Shellenbaum #include <sys/dnode.h> 57fa9e4066Sahrens #include <sys/fs/zfs.h> 58da6c28aaSamw #include <sys/kidmap.h> 5955434c77Sek110237 #endif /* _KERNEL */ 60fa9e4066Sahrens 6155434c77Sek110237 #include <sys/dmu.h> 62b5152584SMatthew Ahrens #include <sys/dmu_objset.h> 6355434c77Sek110237 #include <sys/refcount.h> 6455434c77Sek110237 #include <sys/stat.h> 6555434c77Sek110237 #include <sys/zap.h> 6655434c77Sek110237 #include <sys/zfs_znode.h> 670a586ceaSMark Shellenbaum #include <sys/sa.h> 680a586ceaSMark Shellenbaum #include <sys/zfs_sa.h> 6999d5e173STim Haley #include <sys/zfs_stat.h> 705e286361SAndreas Jaekel #include <sys/zfs_events.h> 7149e90173SAndreas Jaekel #include <zev/zev.h> 7255434c77Sek110237 73de8267e0Stimh #include "zfs_prop.h" 740a586ceaSMark Shellenbaum #include "zfs_comutil.h" 75de8267e0Stimh 7655434c77Sek110237 /* 77b5fca8f8Stomee * Define ZNODE_STATS to turn on statistic gathering. By default, it is only 78b5fca8f8Stomee * turned on when DEBUG is also defined. 79b5fca8f8Stomee */ 80b5fca8f8Stomee #ifdef DEBUG 81b5fca8f8Stomee #define ZNODE_STATS 82b5fca8f8Stomee #endif /* DEBUG */ 83b5fca8f8Stomee 84b5fca8f8Stomee #ifdef ZNODE_STATS 85b5fca8f8Stomee #define ZNODE_STAT_ADD(stat) ((stat)++) 86b5fca8f8Stomee #else 87b5fca8f8Stomee #define ZNODE_STAT_ADD(stat) /* nothing */ 88b5fca8f8Stomee #endif /* ZNODE_STATS */ 89b5fca8f8Stomee 90b5fca8f8Stomee /* 9155434c77Sek110237 * Functions needed for userland (ie: libzpool) are not put under 9255434c77Sek110237 * #ifdef_KERNEL; the rest of the functions have dependencies 9355434c77Sek110237 * (such as VFS logic) that will not compile easily in userland. 9455434c77Sek110237 */ 9555434c77Sek110237 #ifdef _KERNEL 964e9583b2STom Erickson /* 974e9583b2STom Erickson * Needed to close a small window in zfs_znode_move() that allows the zfsvfs to 984e9583b2STom Erickson * be freed before it can be safely accessed. 994e9583b2STom Erickson */ 1004e9583b2STom Erickson krwlock_t zfsvfs_lock; 1014e9583b2STom Erickson 102b5fca8f8Stomee static kmem_cache_t *znode_cache = NULL; 103fa9e4066Sahrens 104fa9e4066Sahrens /*ARGSUSED*/ 105fa9e4066Sahrens static void 106874395d5Smaybee znode_evict_error(dmu_buf_t *dbuf, void *user_ptr) 107fa9e4066Sahrens { 108874395d5Smaybee /* 109874395d5Smaybee * We should never drop all dbuf refs without first clearing 110874395d5Smaybee * the eviction callback. 111874395d5Smaybee */ 112874395d5Smaybee panic("evicting znode %p\n", user_ptr); 113fa9e4066Sahrens } 114fa9e4066Sahrens 115fa9e4066Sahrens /*ARGSUSED*/ 116fa9e4066Sahrens static int 117b5fca8f8Stomee zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) 118fa9e4066Sahrens { 119fa9e4066Sahrens znode_t *zp = buf; 120fa9e4066Sahrens 121b5fca8f8Stomee ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); 122b5fca8f8Stomee 123b5fca8f8Stomee zp->z_vnode = vn_alloc(kmflags); 124b5fca8f8Stomee if (zp->z_vnode == NULL) { 125b5fca8f8Stomee return (-1); 126b5fca8f8Stomee } 127b5fca8f8Stomee ZTOV(zp)->v_data = zp; 128b5fca8f8Stomee 129b5fca8f8Stomee list_link_init(&zp->z_link_node); 130b5fca8f8Stomee 131fa9e4066Sahrens mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); 132104e2ed7Sperrin rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL); 133af2c4821Smaybee rw_init(&zp->z_name_lock, NULL, RW_DEFAULT, NULL); 134fa9e4066Sahrens mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL); 135104e2ed7Sperrin 136104e2ed7Sperrin mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL); 137104e2ed7Sperrin avl_create(&zp->z_range_avl, zfs_range_compare, 138104e2ed7Sperrin sizeof (rl_t), offsetof(rl_t, r_node)); 139104e2ed7Sperrin 140b5fca8f8Stomee zp->z_dirlocks = NULL; 141d47621a4STim Haley zp->z_acl_cached = NULL; 142744947dcSTom Erickson zp->z_moved = 0; 143fa9e4066Sahrens return (0); 144fa9e4066Sahrens } 145fa9e4066Sahrens 146fa9e4066Sahrens /*ARGSUSED*/ 147fa9e4066Sahrens static void 148b5fca8f8Stomee zfs_znode_cache_destructor(void *buf, void *arg) 149fa9e4066Sahrens { 150fa9e4066Sahrens znode_t *zp = buf; 151fa9e4066Sahrens 152b5fca8f8Stomee ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); 153b5fca8f8Stomee ASSERT(ZTOV(zp)->v_data == zp); 154b5fca8f8Stomee vn_free(ZTOV(zp)); 155b5fca8f8Stomee ASSERT(!list_link_active(&zp->z_link_node)); 156fa9e4066Sahrens mutex_destroy(&zp->z_lock); 157104e2ed7Sperrin rw_destroy(&zp->z_parent_lock); 158af2c4821Smaybee rw_destroy(&zp->z_name_lock); 159fa9e4066Sahrens mutex_destroy(&zp->z_acl_lock); 160104e2ed7Sperrin avl_destroy(&zp->z_range_avl); 161c25056deSgw25295 mutex_destroy(&zp->z_range_lock); 162fa9e4066Sahrens 163b5fca8f8Stomee ASSERT(zp->z_dirlocks == NULL); 1644929fd5eSTim Haley ASSERT(zp->z_acl_cached == NULL); 165b5fca8f8Stomee } 166b5fca8f8Stomee 167b5fca8f8Stomee #ifdef ZNODE_STATS 168b5fca8f8Stomee static struct { 169b5fca8f8Stomee uint64_t zms_zfsvfs_invalid; 1704e9583b2STom Erickson uint64_t zms_zfsvfs_recheck1; 171b5fca8f8Stomee uint64_t zms_zfsvfs_unmounted; 1724e9583b2STom Erickson uint64_t zms_zfsvfs_recheck2; 173a66b2b35STom Erickson uint64_t zms_obj_held; 174b5fca8f8Stomee uint64_t zms_vnode_locked; 175a66b2b35STom Erickson uint64_t zms_not_only_dnlc; 176b5fca8f8Stomee } znode_move_stats; 177b5fca8f8Stomee #endif /* ZNODE_STATS */ 178b5fca8f8Stomee 179b5fca8f8Stomee static void 180b5fca8f8Stomee zfs_znode_move_impl(znode_t *ozp, znode_t *nzp) 181b5fca8f8Stomee { 182b5fca8f8Stomee vnode_t *vp; 183b5fca8f8Stomee 184b5fca8f8Stomee /* Copy fields. */ 185b5fca8f8Stomee nzp->z_zfsvfs = ozp->z_zfsvfs; 186b5fca8f8Stomee 187b5fca8f8Stomee /* Swap vnodes. */ 188b5fca8f8Stomee vp = nzp->z_vnode; 189b5fca8f8Stomee nzp->z_vnode = ozp->z_vnode; 190b5fca8f8Stomee ozp->z_vnode = vp; /* let destructor free the overwritten vnode */ 191b5fca8f8Stomee ZTOV(ozp)->v_data = ozp; 192b5fca8f8Stomee ZTOV(nzp)->v_data = nzp; 193b5fca8f8Stomee 194b5fca8f8Stomee nzp->z_id = ozp->z_id; 195b5fca8f8Stomee ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */ 196b5fca8f8Stomee ASSERT(avl_numnodes(&ozp->z_range_avl) == 0); 197b5fca8f8Stomee nzp->z_unlinked = ozp->z_unlinked; 198b5fca8f8Stomee nzp->z_atime_dirty = ozp->z_atime_dirty; 199b5fca8f8Stomee nzp->z_zn_prefetch = ozp->z_zn_prefetch; 200b5fca8f8Stomee nzp->z_blksz = ozp->z_blksz; 201b5fca8f8Stomee nzp->z_seq = ozp->z_seq; 202b5fca8f8Stomee nzp->z_mapcnt = ozp->z_mapcnt; 203b5fca8f8Stomee nzp->z_gen = ozp->z_gen; 204b5fca8f8Stomee nzp->z_sync_cnt = ozp->z_sync_cnt; 2050a586ceaSMark Shellenbaum nzp->z_is_sa = ozp->z_is_sa; 2060a586ceaSMark Shellenbaum nzp->z_sa_hdl = ozp->z_sa_hdl; 2070a586ceaSMark Shellenbaum bcopy(ozp->z_atime, nzp->z_atime, sizeof (uint64_t) * 2); 2080a586ceaSMark Shellenbaum nzp->z_links = ozp->z_links; 2090a586ceaSMark Shellenbaum nzp->z_size = ozp->z_size; 2100a586ceaSMark Shellenbaum nzp->z_pflags = ozp->z_pflags; 2110a586ceaSMark Shellenbaum nzp->z_uid = ozp->z_uid; 2120a586ceaSMark Shellenbaum nzp->z_gid = ozp->z_gid; 2130a586ceaSMark Shellenbaum nzp->z_mode = ozp->z_mode; 214d78b796cSAndreas Jaekel nzp->z_new_content = ozp->z_new_content; 215d98a6232SMark Shellenbaum 216d98a6232SMark Shellenbaum /* 2176638ae1dSMark Shellenbaum * Since this is just an idle znode and kmem is already dealing with 2186638ae1dSMark Shellenbaum * memory pressure, release any cached ACL. 219d98a6232SMark Shellenbaum */ 220d98a6232SMark Shellenbaum if (ozp->z_acl_cached) { 221d98a6232SMark Shellenbaum zfs_acl_free(ozp->z_acl_cached); 222d98a6232SMark Shellenbaum ozp->z_acl_cached = NULL; 223d98a6232SMark Shellenbaum } 224b5fca8f8Stomee 2250a586ceaSMark Shellenbaum sa_set_userp(nzp->z_sa_hdl, nzp); 226b5fca8f8Stomee 227b5fca8f8Stomee /* 228b5fca8f8Stomee * Invalidate the original znode by clearing fields that provide a 229b5fca8f8Stomee * pointer back to the znode. Set the low bit of the vfs pointer to 230b5fca8f8Stomee * ensure that zfs_znode_move() recognizes the znode as invalid in any 231b5fca8f8Stomee * subsequent callback. 232b5fca8f8Stomee */ 2330a586ceaSMark Shellenbaum ozp->z_sa_hdl = NULL; 234b5fca8f8Stomee POINTER_INVALIDATE(&ozp->z_zfsvfs); 235744947dcSTom Erickson 236744947dcSTom Erickson /* 237744947dcSTom Erickson * Mark the znode. 238744947dcSTom Erickson */ 239744947dcSTom Erickson nzp->z_moved = 1; 240744947dcSTom Erickson ozp->z_moved = (uint8_t)-1; 241b5fca8f8Stomee } 242b5fca8f8Stomee 243b5fca8f8Stomee /*ARGSUSED*/ 244b5fca8f8Stomee static kmem_cbrc_t 245b5fca8f8Stomee zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg) 246b5fca8f8Stomee { 247b5fca8f8Stomee znode_t *ozp = buf, *nzp = newbuf; 248b5fca8f8Stomee zfsvfs_t *zfsvfs; 249b5fca8f8Stomee vnode_t *vp; 250b5fca8f8Stomee 251b5fca8f8Stomee /* 252b5fca8f8Stomee * The znode is on the file system's list of known znodes if the vfs 253b5fca8f8Stomee * pointer is valid. We set the low bit of the vfs pointer when freeing 254b5fca8f8Stomee * the znode to invalidate it, and the memory patterns written by kmem 255b5fca8f8Stomee * (baddcafe and deadbeef) set at least one of the two low bits. A newly 256b5fca8f8Stomee * created znode sets the vfs pointer last of all to indicate that the 257b5fca8f8Stomee * znode is known and in a valid state to be moved by this function. 258b5fca8f8Stomee */ 259b5fca8f8Stomee zfsvfs = ozp->z_zfsvfs; 260b5fca8f8Stomee if (!POINTER_IS_VALID(zfsvfs)) { 261b5fca8f8Stomee ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_invalid); 262b5fca8f8Stomee return (KMEM_CBRC_DONT_KNOW); 263b5fca8f8Stomee } 264b5fca8f8Stomee 265b5fca8f8Stomee /* 2664e9583b2STom Erickson * Close a small window in which it's possible that the filesystem could 2674e9583b2STom Erickson * be unmounted and freed, and zfsvfs, though valid in the previous 2684e9583b2STom Erickson * statement, could point to unrelated memory by the time we try to 2694e9583b2STom Erickson * prevent the filesystem from being unmounted. 2704e9583b2STom Erickson */ 2714e9583b2STom Erickson rw_enter(&zfsvfs_lock, RW_WRITER); 2724e9583b2STom Erickson if (zfsvfs != ozp->z_zfsvfs) { 2734e9583b2STom Erickson rw_exit(&zfsvfs_lock); 2744e9583b2STom Erickson ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck1); 2754e9583b2STom Erickson return (KMEM_CBRC_DONT_KNOW); 2764e9583b2STom Erickson } 2774e9583b2STom Erickson 2784e9583b2STom Erickson /* 2794e9583b2STom Erickson * If the znode is still valid, then so is the file system. We know that 2804e9583b2STom Erickson * no valid file system can be freed while we hold zfsvfs_lock, so we 2814e9583b2STom Erickson * can safely ensure that the filesystem is not and will not be 2824e9583b2STom Erickson * unmounted. The next statement is equivalent to ZFS_ENTER(). 283b5fca8f8Stomee */ 284c9030f6cSAlexander Motin rrm_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG); 28514843421SMatthew Ahrens if (zfsvfs->z_unmounted) { 28614843421SMatthew Ahrens ZFS_EXIT(zfsvfs); 2874e9583b2STom Erickson rw_exit(&zfsvfs_lock); 288b5fca8f8Stomee ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted); 289b5fca8f8Stomee return (KMEM_CBRC_DONT_KNOW); 290b5fca8f8Stomee } 2914e9583b2STom Erickson rw_exit(&zfsvfs_lock); 292b5fca8f8Stomee 293b5fca8f8Stomee mutex_enter(&zfsvfs->z_znodes_lock); 294b5fca8f8Stomee /* 295b5fca8f8Stomee * Recheck the vfs pointer in case the znode was removed just before 296b5fca8f8Stomee * acquiring the lock. 297b5fca8f8Stomee */ 298b5fca8f8Stomee if (zfsvfs != ozp->z_zfsvfs) { 299b5fca8f8Stomee mutex_exit(&zfsvfs->z_znodes_lock); 300b5fca8f8Stomee ZFS_EXIT(zfsvfs); 3014e9583b2STom Erickson ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck2); 302b5fca8f8Stomee return (KMEM_CBRC_DONT_KNOW); 303b5fca8f8Stomee } 304b5fca8f8Stomee 305b5fca8f8Stomee /* 306b5fca8f8Stomee * At this point we know that as long as we hold z_znodes_lock, the 307b5fca8f8Stomee * znode cannot be freed and fields within the znode can be safely 308a66b2b35STom Erickson * accessed. Now, prevent a race with zfs_zget(). 309b5fca8f8Stomee */ 310a66b2b35STom Erickson if (ZFS_OBJ_HOLD_TRYENTER(zfsvfs, ozp->z_id) == 0) { 311a66b2b35STom Erickson mutex_exit(&zfsvfs->z_znodes_lock); 312a66b2b35STom Erickson ZFS_EXIT(zfsvfs); 313a66b2b35STom Erickson ZNODE_STAT_ADD(znode_move_stats.zms_obj_held); 314a66b2b35STom Erickson return (KMEM_CBRC_LATER); 315a66b2b35STom Erickson } 316a66b2b35STom Erickson 317b5fca8f8Stomee vp = ZTOV(ozp); 318b5fca8f8Stomee if (mutex_tryenter(&vp->v_lock) == 0) { 319a66b2b35STom Erickson ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); 320b5fca8f8Stomee mutex_exit(&zfsvfs->z_znodes_lock); 321b5fca8f8Stomee ZFS_EXIT(zfsvfs); 322b5fca8f8Stomee ZNODE_STAT_ADD(znode_move_stats.zms_vnode_locked); 323b5fca8f8Stomee return (KMEM_CBRC_LATER); 324b5fca8f8Stomee } 325a66b2b35STom Erickson 326b5fca8f8Stomee /* Only move znodes that are referenced _only_ by the DNLC. */ 327b5fca8f8Stomee if (vp->v_count != 1 || !vn_in_dnlc(vp)) { 328b5fca8f8Stomee mutex_exit(&vp->v_lock); 329a66b2b35STom Erickson ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); 330b5fca8f8Stomee mutex_exit(&zfsvfs->z_znodes_lock); 331b5fca8f8Stomee ZFS_EXIT(zfsvfs); 332a66b2b35STom Erickson ZNODE_STAT_ADD(znode_move_stats.zms_not_only_dnlc); 333b5fca8f8Stomee return (KMEM_CBRC_LATER); 334b5fca8f8Stomee } 335b5fca8f8Stomee 336b5fca8f8Stomee /* 337b5fca8f8Stomee * The znode is known and in a valid state to move. We're holding the 338b5fca8f8Stomee * locks needed to execute the critical section. 339b5fca8f8Stomee */ 340b5fca8f8Stomee zfs_znode_move_impl(ozp, nzp); 341b5fca8f8Stomee mutex_exit(&vp->v_lock); 342a66b2b35STom Erickson ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); 343b5fca8f8Stomee 344b5fca8f8Stomee list_link_replace(&ozp->z_link_node, &nzp->z_link_node); 345b5fca8f8Stomee mutex_exit(&zfsvfs->z_znodes_lock); 346b5fca8f8Stomee ZFS_EXIT(zfsvfs); 347b5fca8f8Stomee 348b5fca8f8Stomee return (KMEM_CBRC_YES); 349fa9e4066Sahrens } 350fa9e4066Sahrens 351fa9e4066Sahrens void 352fa9e4066Sahrens zfs_znode_init(void) 353fa9e4066Sahrens { 354fa9e4066Sahrens /* 355fa9e4066Sahrens * Initialize zcache 356fa9e4066Sahrens */ 3574e9583b2STom Erickson rw_init(&zfsvfs_lock, NULL, RW_DEFAULT, NULL); 358fa9e4066Sahrens ASSERT(znode_cache == NULL); 359fa9e4066Sahrens znode_cache = kmem_cache_create("zfs_znode_cache", 360fa9e4066Sahrens sizeof (znode_t), 0, zfs_znode_cache_constructor, 361fa9e4066Sahrens zfs_znode_cache_destructor, NULL, NULL, NULL, 0); 362b5fca8f8Stomee kmem_cache_set_move(znode_cache, zfs_znode_move); 363fa9e4066Sahrens } 364fa9e4066Sahrens 365fa9e4066Sahrens void 366fa9e4066Sahrens zfs_znode_fini(void) 367fa9e4066Sahrens { 368fa9e4066Sahrens /* 369fa9e4066Sahrens * Cleanup vfs & vnode ops 370fa9e4066Sahrens */ 371fa9e4066Sahrens zfs_remove_op_tables(); 372fa9e4066Sahrens 373fa9e4066Sahrens /* 374fa9e4066Sahrens * Cleanup zcache 375fa9e4066Sahrens */ 376fa9e4066Sahrens if (znode_cache) 377fa9e4066Sahrens kmem_cache_destroy(znode_cache); 378fa9e4066Sahrens znode_cache = NULL; 3794e9583b2STom Erickson rw_destroy(&zfsvfs_lock); 380fa9e4066Sahrens } 381fa9e4066Sahrens 382fa9e4066Sahrens struct vnodeops *zfs_dvnodeops; 383fa9e4066Sahrens struct vnodeops *zfs_fvnodeops; 384fa9e4066Sahrens struct vnodeops *zfs_symvnodeops; 385fa9e4066Sahrens struct vnodeops *zfs_xdvnodeops; 386fa9e4066Sahrens struct vnodeops *zfs_evnodeops; 387743a77edSAlan Wright struct vnodeops *zfs_sharevnodeops; 388fa9e4066Sahrens 389fa9e4066Sahrens void 390fa9e4066Sahrens zfs_remove_op_tables() 391fa9e4066Sahrens { 392fa9e4066Sahrens /* 393fa9e4066Sahrens * Remove vfs ops 394fa9e4066Sahrens */ 395fa9e4066Sahrens ASSERT(zfsfstype); 396fa9e4066Sahrens (void) vfs_freevfsops_by_type(zfsfstype); 397fa9e4066Sahrens zfsfstype = 0; 398fa9e4066Sahrens 399fa9e4066Sahrens /* 400fa9e4066Sahrens * Remove vnode ops 401fa9e4066Sahrens */ 402fa9e4066Sahrens if (zfs_dvnodeops) 403fa9e4066Sahrens vn_freevnodeops(zfs_dvnodeops); 404fa9e4066Sahrens if (zfs_fvnodeops) 405fa9e4066Sahrens vn_freevnodeops(zfs_fvnodeops); 406fa9e4066Sahrens if (zfs_symvnodeops) 407fa9e4066Sahrens vn_freevnodeops(zfs_symvnodeops); 408fa9e4066Sahrens if (zfs_xdvnodeops) 409fa9e4066Sahrens vn_freevnodeops(zfs_xdvnodeops); 410fa9e4066Sahrens if (zfs_evnodeops) 411fa9e4066Sahrens vn_freevnodeops(zfs_evnodeops); 412743a77edSAlan Wright if (zfs_sharevnodeops) 413743a77edSAlan Wright vn_freevnodeops(zfs_sharevnodeops); 414fa9e4066Sahrens 415fa9e4066Sahrens zfs_dvnodeops = NULL; 416fa9e4066Sahrens zfs_fvnodeops = NULL; 417fa9e4066Sahrens zfs_symvnodeops = NULL; 418fa9e4066Sahrens zfs_xdvnodeops = NULL; 419fa9e4066Sahrens zfs_evnodeops = NULL; 420743a77edSAlan Wright zfs_sharevnodeops = NULL; 421fa9e4066Sahrens } 422fa9e4066Sahrens 423fa9e4066Sahrens extern const fs_operation_def_t zfs_dvnodeops_template[]; 424fa9e4066Sahrens extern const fs_operation_def_t zfs_fvnodeops_template[]; 425fa9e4066Sahrens extern const fs_operation_def_t zfs_xdvnodeops_template[]; 426fa9e4066Sahrens extern const fs_operation_def_t zfs_symvnodeops_template[]; 427fa9e4066Sahrens extern const fs_operation_def_t zfs_evnodeops_template[]; 428743a77edSAlan Wright extern const fs_operation_def_t zfs_sharevnodeops_template[]; 429fa9e4066Sahrens 430fa9e4066Sahrens int 431fa9e4066Sahrens zfs_create_op_tables() 432fa9e4066Sahrens { 433fa9e4066Sahrens int error; 434fa9e4066Sahrens 435fa9e4066Sahrens /* 436fa9e4066Sahrens * zfs_dvnodeops can be set if mod_remove() calls mod_installfs() 437fa9e4066Sahrens * due to a failure to remove the the 2nd modlinkage (zfs_modldrv). 438fa9e4066Sahrens * In this case we just return as the ops vectors are already set up. 439fa9e4066Sahrens */ 440fa9e4066Sahrens if (zfs_dvnodeops) 441fa9e4066Sahrens return (0); 442fa9e4066Sahrens 443fa9e4066Sahrens error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template, 444fa9e4066Sahrens &zfs_dvnodeops); 445fa9e4066Sahrens if (error) 446fa9e4066Sahrens return (error); 447fa9e4066Sahrens 448fa9e4066Sahrens error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template, 449fa9e4066Sahrens &zfs_fvnodeops); 450fa9e4066Sahrens if (error) 451fa9e4066Sahrens return (error); 452fa9e4066Sahrens 453fa9e4066Sahrens error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template, 454fa9e4066Sahrens &zfs_symvnodeops); 455fa9e4066Sahrens if (error) 456fa9e4066Sahrens return (error); 457fa9e4066Sahrens 458fa9e4066Sahrens error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template, 459fa9e4066Sahrens &zfs_xdvnodeops); 460fa9e4066Sahrens if (error) 461fa9e4066Sahrens return (error); 462fa9e4066Sahrens 463fa9e4066Sahrens error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template, 464fa9e4066Sahrens &zfs_evnodeops); 465743a77edSAlan Wright if (error) 466743a77edSAlan Wright return (error); 467743a77edSAlan Wright 468743a77edSAlan Wright error = vn_make_ops(MNTTYPE_ZFS, zfs_sharevnodeops_template, 469743a77edSAlan Wright &zfs_sharevnodeops); 470743a77edSAlan Wright 471743a77edSAlan Wright return (error); 472743a77edSAlan Wright } 473743a77edSAlan Wright 4749e1320c0SMark Shellenbaum int 475743a77edSAlan Wright zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) 476743a77edSAlan Wright { 47789459e17SMark Shellenbaum zfs_acl_ids_t acl_ids; 478743a77edSAlan Wright vattr_t vattr; 479743a77edSAlan Wright znode_t *sharezp; 480743a77edSAlan Wright vnode_t *vp; 481743a77edSAlan Wright znode_t *zp; 482743a77edSAlan Wright int error; 483743a77edSAlan Wright 484743a77edSAlan Wright vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; 485743a77edSAlan Wright vattr.va_type = VDIR; 486743a77edSAlan Wright vattr.va_mode = S_IFDIR|0555; 487743a77edSAlan Wright vattr.va_uid = crgetuid(kcred); 488743a77edSAlan Wright vattr.va_gid = crgetgid(kcred); 489743a77edSAlan Wright 490743a77edSAlan Wright sharezp = kmem_cache_alloc(znode_cache, KM_SLEEP); 491744947dcSTom Erickson ASSERT(!POINTER_IS_VALID(sharezp->z_zfsvfs)); 492744947dcSTom Erickson sharezp->z_moved = 0; 493743a77edSAlan Wright sharezp->z_unlinked = 0; 494743a77edSAlan Wright sharezp->z_atime_dirty = 0; 495743a77edSAlan Wright sharezp->z_zfsvfs = zfsvfs; 4960a586ceaSMark Shellenbaum sharezp->z_is_sa = zfsvfs->z_use_sa; 497743a77edSAlan Wright 498743a77edSAlan Wright vp = ZTOV(sharezp); 499743a77edSAlan Wright vn_reinit(vp); 500743a77edSAlan Wright vp->v_type = VDIR; 501743a77edSAlan Wright 50289459e17SMark Shellenbaum VERIFY(0 == zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr, 50389459e17SMark Shellenbaum kcred, NULL, &acl_ids)); 5040a586ceaSMark Shellenbaum zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids); 505743a77edSAlan Wright ASSERT3P(zp, ==, sharezp); 506743a77edSAlan Wright ASSERT(!vn_in_dnlc(ZTOV(sharezp))); /* not valid to move */ 507743a77edSAlan Wright POINTER_INVALIDATE(&sharezp->z_zfsvfs); 508743a77edSAlan Wright error = zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, 509743a77edSAlan Wright ZFS_SHARES_DIR, 8, 1, &sharezp->z_id, tx); 510743a77edSAlan Wright zfsvfs->z_shares_dir = sharezp->z_id; 511743a77edSAlan Wright 51289459e17SMark Shellenbaum zfs_acl_ids_free(&acl_ids); 513743a77edSAlan Wright ZTOV(sharezp)->v_count = 0; 5140a586ceaSMark Shellenbaum sa_handle_destroy(sharezp->z_sa_hdl); 515743a77edSAlan Wright kmem_cache_free(znode_cache, sharezp); 516fa9e4066Sahrens 517fa9e4066Sahrens return (error); 518fa9e4066Sahrens } 519fa9e4066Sahrens 520fa9e4066Sahrens /* 52172fc53bcSmarks * define a couple of values we need available 52272fc53bcSmarks * for both 64 and 32 bit environments. 52372fc53bcSmarks */ 52472fc53bcSmarks #ifndef NBITSMINOR64 52572fc53bcSmarks #define NBITSMINOR64 32 52672fc53bcSmarks #endif 52772fc53bcSmarks #ifndef MAXMAJ64 52872fc53bcSmarks #define MAXMAJ64 0xffffffffUL 52972fc53bcSmarks #endif 53072fc53bcSmarks #ifndef MAXMIN64 53172fc53bcSmarks #define MAXMIN64 0xffffffffUL 53272fc53bcSmarks #endif 53372fc53bcSmarks 53472fc53bcSmarks /* 53572fc53bcSmarks * Create special expldev for ZFS private use. 53672fc53bcSmarks * Can't use standard expldev since it doesn't do 53772fc53bcSmarks * what we want. The standard expldev() takes a 53872fc53bcSmarks * dev32_t in LP64 and expands it to a long dev_t. 53972fc53bcSmarks * We need an interface that takes a dev32_t in ILP32 54072fc53bcSmarks * and expands it to a long dev_t. 54172fc53bcSmarks */ 54272fc53bcSmarks static uint64_t 54372fc53bcSmarks zfs_expldev(dev_t dev) 54472fc53bcSmarks { 54572fc53bcSmarks #ifndef _LP64 54672fc53bcSmarks major_t major = (major_t)dev >> NBITSMINOR32 & MAXMAJ32; 54772fc53bcSmarks return (((uint64_t)major << NBITSMINOR64) | 54872fc53bcSmarks ((minor_t)dev & MAXMIN32)); 54972fc53bcSmarks #else 55072fc53bcSmarks return (dev); 55172fc53bcSmarks #endif 55272fc53bcSmarks } 55372fc53bcSmarks 55472fc53bcSmarks /* 55572fc53bcSmarks * Special cmpldev for ZFS private use. 55672fc53bcSmarks * Can't use standard cmpldev since it takes 55772fc53bcSmarks * a long dev_t and compresses it to dev32_t in 55872fc53bcSmarks * LP64. We need to do a compaction of a long dev_t 55972fc53bcSmarks * to a dev32_t in ILP32. 56072fc53bcSmarks */ 56172fc53bcSmarks dev_t 56272fc53bcSmarks zfs_cmpldev(uint64_t dev) 56372fc53bcSmarks { 56472fc53bcSmarks #ifndef _LP64 56572fc53bcSmarks minor_t minor = (minor_t)dev & MAXMIN64; 56672fc53bcSmarks major_t major = (major_t)(dev >> NBITSMINOR64) & MAXMAJ64; 56772fc53bcSmarks 56872fc53bcSmarks if (major > MAXMAJ32 || minor > MAXMIN32) 56972fc53bcSmarks return (NODEV32); 57072fc53bcSmarks 57172fc53bcSmarks return (((dev32_t)major << NBITSMINOR32) | minor); 57272fc53bcSmarks #else 57372fc53bcSmarks return (dev); 57472fc53bcSmarks #endif 57572fc53bcSmarks } 57672fc53bcSmarks 5774ccbb6e7Sahrens static void 5780a586ceaSMark Shellenbaum zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp, 5790a586ceaSMark Shellenbaum dmu_buf_t *db, dmu_object_type_t obj_type, sa_handle_t *sa_hdl) 5804ccbb6e7Sahrens { 581b5fca8f8Stomee ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs)); 582b5fca8f8Stomee ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id))); 5834ccbb6e7Sahrens 5844ccbb6e7Sahrens mutex_enter(&zp->z_lock); 5854ccbb6e7Sahrens 5860a586ceaSMark Shellenbaum ASSERT(zp->z_sa_hdl == NULL); 5876638ae1dSMark Shellenbaum ASSERT(zp->z_acl_cached == NULL); 5880a586ceaSMark Shellenbaum if (sa_hdl == NULL) { 5890a586ceaSMark Shellenbaum VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, zp, 5900a586ceaSMark Shellenbaum SA_HDL_SHARED, &zp->z_sa_hdl)); 5910a586ceaSMark Shellenbaum } else { 5920a586ceaSMark Shellenbaum zp->z_sa_hdl = sa_hdl; 5930a586ceaSMark Shellenbaum sa_set_userp(sa_hdl, zp); 5940a586ceaSMark Shellenbaum } 5954ccbb6e7Sahrens 5960a586ceaSMark Shellenbaum zp->z_is_sa = (obj_type == DMU_OT_SA) ? B_TRUE : B_FALSE; 5974ccbb6e7Sahrens 5984ccbb6e7Sahrens /* 5994ccbb6e7Sahrens * Slap on VROOT if we are the root znode 6004ccbb6e7Sahrens */ 6014ccbb6e7Sahrens if (zp->z_id == zfsvfs->z_root) 6024ccbb6e7Sahrens ZTOV(zp)->v_flag |= VROOT; 6034ccbb6e7Sahrens 6044ccbb6e7Sahrens mutex_exit(&zp->z_lock); 6054ccbb6e7Sahrens vn_exists(ZTOV(zp)); 6064ccbb6e7Sahrens } 6074ccbb6e7Sahrens 608874395d5Smaybee void 6094ccbb6e7Sahrens zfs_znode_dmu_fini(znode_t *zp) 6104ccbb6e7Sahrens { 611b5fca8f8Stomee ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp->z_zfsvfs, zp->z_id)) || 612b5fca8f8Stomee zp->z_unlinked || 613874395d5Smaybee RW_WRITE_HELD(&zp->z_zfsvfs->z_teardown_inactive_lock)); 6140a586ceaSMark Shellenbaum 6150a586ceaSMark Shellenbaum sa_handle_destroy(zp->z_sa_hdl); 6160a586ceaSMark Shellenbaum zp->z_sa_hdl = NULL; 6174ccbb6e7Sahrens } 6184ccbb6e7Sahrens 61972fc53bcSmarks /* 620fa9e4066Sahrens * Construct a new znode/vnode and intialize. 621fa9e4066Sahrens * 622fa9e4066Sahrens * This does not do a call to dmu_set_user() that is 623fa9e4066Sahrens * up to the caller to do, in case you don't want to 624fa9e4066Sahrens * return the znode 625fa9e4066Sahrens */ 626ea8dc4b6Seschrock static znode_t * 6270a586ceaSMark Shellenbaum zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, 6280a586ceaSMark Shellenbaum dmu_object_type_t obj_type, sa_handle_t *hdl) 629fa9e4066Sahrens { 630fa9e4066Sahrens znode_t *zp; 631fa9e4066Sahrens vnode_t *vp; 6320a586ceaSMark Shellenbaum uint64_t mode; 6330a586ceaSMark Shellenbaum uint64_t parent; 6340a586ceaSMark Shellenbaum sa_bulk_attr_t bulk[9]; 6350a586ceaSMark Shellenbaum int count = 0; 636fa9e4066Sahrens 637fa9e4066Sahrens zp = kmem_cache_alloc(znode_cache, KM_SLEEP); 638fa9e4066Sahrens 639fa9e4066Sahrens ASSERT(zp->z_dirlocks == NULL); 640b5fca8f8Stomee ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); 641744947dcSTom Erickson zp->z_moved = 0; 642fa9e4066Sahrens 643b5fca8f8Stomee /* 644b5fca8f8Stomee * Defer setting z_zfsvfs until the znode is ready to be a candidate for 645b5fca8f8Stomee * the zfs_znode_move() callback. 646b5fca8f8Stomee */ 6470a586ceaSMark Shellenbaum zp->z_sa_hdl = NULL; 648893a6d32Sahrens zp->z_unlinked = 0; 649fa9e4066Sahrens zp->z_atime_dirty = 0; 650fa9e4066Sahrens zp->z_mapcnt = 0; 6514ccbb6e7Sahrens zp->z_id = db->db_object; 652fa9e4066Sahrens zp->z_blksz = blksz; 653fa9e4066Sahrens zp->z_seq = 0x7A4653; 65467bd71c6Sperrin zp->z_sync_cnt = 0; 655d78b796cSAndreas Jaekel zp->z_new_content = 0; 6564ccbb6e7Sahrens 6574ccbb6e7Sahrens vp = ZTOV(zp); 6584ccbb6e7Sahrens vn_reinit(vp); 6594ccbb6e7Sahrens 6600a586ceaSMark Shellenbaum zfs_znode_sa_init(zfsvfs, zp, db, obj_type, hdl); 6614ccbb6e7Sahrens 6620a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); 6630a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, &zp->z_gen, 8); 6640a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, 6650a586ceaSMark Shellenbaum &zp->z_size, 8); 6660a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, 6670a586ceaSMark Shellenbaum &zp->z_links, 8); 6680a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, 6690a586ceaSMark Shellenbaum &zp->z_pflags, 8); 6700a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8); 6710a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, 6720a586ceaSMark Shellenbaum &zp->z_atime, 16); 6730a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, 674f1696b23SMark Shellenbaum &zp->z_uid, 8); 6750a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, 676f1696b23SMark Shellenbaum &zp->z_gid, 8); 677fa9e4066Sahrens 6780a586ceaSMark Shellenbaum if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) { 6790a586ceaSMark Shellenbaum if (hdl == NULL) 6800a586ceaSMark Shellenbaum sa_handle_destroy(zp->z_sa_hdl); 6810a586ceaSMark Shellenbaum kmem_cache_free(znode_cache, zp); 6820a586ceaSMark Shellenbaum return (NULL); 6830a586ceaSMark Shellenbaum } 6840a586ceaSMark Shellenbaum 6850a586ceaSMark Shellenbaum zp->z_mode = mode; 686fa9e4066Sahrens vp->v_vfsp = zfsvfs->z_parent->z_vfs; 6870a586ceaSMark Shellenbaum 6880a586ceaSMark Shellenbaum vp->v_type = IFTOVT((mode_t)mode); 689fa9e4066Sahrens 690fa9e4066Sahrens switch (vp->v_type) { 691fa9e4066Sahrens case VDIR: 6920a586ceaSMark Shellenbaum if (zp->z_pflags & ZFS_XATTR) { 693fa9e4066Sahrens vn_setops(vp, zfs_xdvnodeops); 694fa9e4066Sahrens vp->v_flag |= V_XATTRDIR; 6954ccbb6e7Sahrens } else { 696fa9e4066Sahrens vn_setops(vp, zfs_dvnodeops); 6974ccbb6e7Sahrens } 6987f6e3e7dSperrin zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ 699fa9e4066Sahrens break; 700fa9e4066Sahrens case VBLK: 701fa9e4066Sahrens case VCHR: 7020a586ceaSMark Shellenbaum { 7030a586ceaSMark Shellenbaum uint64_t rdev; 7040a586ceaSMark Shellenbaum VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs), 7050a586ceaSMark Shellenbaum &rdev, sizeof (rdev)) == 0); 7060a586ceaSMark Shellenbaum 7070a586ceaSMark Shellenbaum vp->v_rdev = zfs_cmpldev(rdev); 7080a586ceaSMark Shellenbaum } 709fa9e4066Sahrens /*FALLTHROUGH*/ 710fa9e4066Sahrens case VFIFO: 711fa9e4066Sahrens case VSOCK: 712fa9e4066Sahrens case VDOOR: 713fa9e4066Sahrens vn_setops(vp, zfs_fvnodeops); 714fa9e4066Sahrens break; 715fa9e4066Sahrens case VREG: 716fa9e4066Sahrens vp->v_flag |= VMODSORT; 7170a586ceaSMark Shellenbaum if (parent == zfsvfs->z_shares_dir) { 718f1696b23SMark Shellenbaum ASSERT(zp->z_uid == 0 && zp->z_gid == 0); 719743a77edSAlan Wright vn_setops(vp, zfs_sharevnodeops); 7200a586ceaSMark Shellenbaum } else { 721fa9e4066Sahrens vn_setops(vp, zfs_fvnodeops); 7220a586ceaSMark Shellenbaum } 723fa9e4066Sahrens break; 724fa9e4066Sahrens case VLNK: 725fa9e4066Sahrens vn_setops(vp, zfs_symvnodeops); 726fa9e4066Sahrens break; 727fa9e4066Sahrens default: 728fa9e4066Sahrens vn_setops(vp, zfs_evnodeops); 729fa9e4066Sahrens break; 730fa9e4066Sahrens } 731fa9e4066Sahrens 732b5fca8f8Stomee mutex_enter(&zfsvfs->z_znodes_lock); 733b5fca8f8Stomee list_insert_tail(&zfsvfs->z_all_znodes, zp); 734b5fca8f8Stomee membar_producer(); 735b5fca8f8Stomee /* 736b5fca8f8Stomee * Everything else must be valid before assigning z_zfsvfs makes the 737b5fca8f8Stomee * znode eligible for zfs_znode_move(). 738b5fca8f8Stomee */ 739b5fca8f8Stomee zp->z_zfsvfs = zfsvfs; 740b5fca8f8Stomee mutex_exit(&zfsvfs->z_znodes_lock); 741b5fca8f8Stomee 742fa9e4066Sahrens VFS_HOLD(zfsvfs->z_vfs); 7434ccbb6e7Sahrens return (zp); 744fa9e4066Sahrens } 745fa9e4066Sahrens 7460a586ceaSMark Shellenbaum static uint64_t empty_xattr; 7470a586ceaSMark Shellenbaum static uint64_t pad[4]; 7480a586ceaSMark Shellenbaum static zfs_acl_phys_t acl_phys; 749fa9e4066Sahrens /* 750fa9e4066Sahrens * Create a new DMU object to hold a zfs znode. 751fa9e4066Sahrens * 752fa9e4066Sahrens * IN: dzp - parent directory for new znode 753fa9e4066Sahrens * vap - file attributes for new znode 754fa9e4066Sahrens * tx - dmu transaction id for zap operations 755fa9e4066Sahrens * cr - credentials of caller 756fa9e4066Sahrens * flag - flags: 757fa9e4066Sahrens * IS_ROOT_NODE - new object will be root 758fa9e4066Sahrens * IS_XATTR - new object is an attribute 759da6c28aaSamw * bonuslen - length of bonus buffer 760da6c28aaSamw * setaclp - File/Dir initial ACL 761da6c28aaSamw * fuidp - Tracks fuid allocation. 762fa9e4066Sahrens * 7634ccbb6e7Sahrens * OUT: zpp - allocated znode 764fa9e4066Sahrens * 765fa9e4066Sahrens */ 766fa9e4066Sahrens void 7674ccbb6e7Sahrens zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, 7680a586ceaSMark Shellenbaum uint_t flag, znode_t **zpp, zfs_acl_ids_t *acl_ids) 769fa9e4066Sahrens { 7700a586ceaSMark Shellenbaum uint64_t crtime[2], atime[2], mtime[2], ctime[2]; 7710a586ceaSMark Shellenbaum uint64_t mode, size, links, parent, pflags; 7720a586ceaSMark Shellenbaum uint64_t dzp_pflags = 0; 7730a586ceaSMark Shellenbaum uint64_t rdev = 0; 774fa9e4066Sahrens zfsvfs_t *zfsvfs = dzp->z_zfsvfs; 7750a586ceaSMark Shellenbaum dmu_buf_t *db; 776fa9e4066Sahrens timestruc_t now; 7774ccbb6e7Sahrens uint64_t gen, obj; 7780a586ceaSMark Shellenbaum int bonuslen; 7790a586ceaSMark Shellenbaum sa_handle_t *sa_hdl; 7800a586ceaSMark Shellenbaum dmu_object_type_t obj_type; 7810a586ceaSMark Shellenbaum sa_bulk_attr_t sa_attrs[ZPL_END]; 7820a586ceaSMark Shellenbaum int cnt = 0; 7830a586ceaSMark Shellenbaum zfs_acl_locator_cb_t locate = { 0 }; 784fa9e4066Sahrens 785fa9e4066Sahrens ASSERT(vap && (vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE)); 786fa9e4066Sahrens 7871209a471SNeil Perrin if (zfsvfs->z_replay) { 7884ccbb6e7Sahrens obj = vap->va_nodeid; 789fa9e4066Sahrens now = vap->va_ctime; /* see zfs_replay_create() */ 790fa9e4066Sahrens gen = vap->va_nblocks; /* ditto */ 791fa9e4066Sahrens } else { 7924ccbb6e7Sahrens obj = 0; 793fa9e4066Sahrens gethrestime(&now); 794fa9e4066Sahrens gen = dmu_tx_get_txg(tx); 795fa9e4066Sahrens } 796fa9e4066Sahrens 7970a586ceaSMark Shellenbaum obj_type = zfsvfs->z_use_sa ? DMU_OT_SA : DMU_OT_ZNODE; 7980a586ceaSMark Shellenbaum bonuslen = (obj_type == DMU_OT_SA) ? 7990a586ceaSMark Shellenbaum DN_MAX_BONUSLEN : ZFS_OLD_ZNODE_PHYS_SIZE; 8000a586ceaSMark Shellenbaum 801fa9e4066Sahrens /* 802fa9e4066Sahrens * Create a new DMU object. 803fa9e4066Sahrens */ 804ea8dc4b6Seschrock /* 805ea8dc4b6Seschrock * There's currently no mechanism for pre-reading the blocks that will 806744947dcSTom Erickson * be needed to allocate a new object, so we accept the small chance 807ea8dc4b6Seschrock * that there will be an i/o error and we will fail one of the 808ea8dc4b6Seschrock * assertions below. 809ea8dc4b6Seschrock */ 810fa9e4066Sahrens if (vap->va_type == VDIR) { 8114a1f0cc9SMark Shellenbaum if (zfsvfs->z_replay) { 81243466aaeSMax Grossman VERIFY0(zap_create_claim_norm(zfsvfs->z_os, obj, 813da6c28aaSamw zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, 81443466aaeSMax Grossman obj_type, bonuslen, tx)); 815fa9e4066Sahrens } else { 8164ccbb6e7Sahrens obj = zap_create_norm(zfsvfs->z_os, 817da6c28aaSamw zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, 8180a586ceaSMark Shellenbaum obj_type, bonuslen, tx); 819fa9e4066Sahrens } 820fa9e4066Sahrens } else { 8214a1f0cc9SMark Shellenbaum if (zfsvfs->z_replay) { 82243466aaeSMax Grossman VERIFY0(dmu_object_claim(zfsvfs->z_os, obj, 823fa9e4066Sahrens DMU_OT_PLAIN_FILE_CONTENTS, 0, 82443466aaeSMax Grossman obj_type, bonuslen, tx)); 825fa9e4066Sahrens } else { 8264ccbb6e7Sahrens obj = dmu_object_alloc(zfsvfs->z_os, 827fa9e4066Sahrens DMU_OT_PLAIN_FILE_CONTENTS, 0, 8280a586ceaSMark Shellenbaum obj_type, bonuslen, tx); 829fa9e4066Sahrens } 830fa9e4066Sahrens } 83159e7834dSMark Shellenbaum 83259e7834dSMark Shellenbaum ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); 8330a586ceaSMark Shellenbaum VERIFY(0 == sa_buf_hold(zfsvfs->z_os, obj, NULL, &db)); 834fa9e4066Sahrens 835fa9e4066Sahrens /* 836fa9e4066Sahrens * If this is the root, fix up the half-initialized parent pointer 837fa9e4066Sahrens * to reference the just-allocated physical data area. 838fa9e4066Sahrens */ 839fa9e4066Sahrens if (flag & IS_ROOT_NODE) { 8404ccbb6e7Sahrens dzp->z_id = obj; 8410a586ceaSMark Shellenbaum } else { 8420a586ceaSMark Shellenbaum dzp_pflags = dzp->z_pflags; 843fa9e4066Sahrens } 844fa9e4066Sahrens 845fa9e4066Sahrens /* 846fa9e4066Sahrens * If parent is an xattr, so am I. 847fa9e4066Sahrens */ 8480a586ceaSMark Shellenbaum if (dzp_pflags & ZFS_XATTR) { 849fa9e4066Sahrens flag |= IS_XATTR; 850fa9e4066Sahrens } 851fa9e4066Sahrens 852da6c28aaSamw if (zfsvfs->z_use_fuids) 8530a586ceaSMark Shellenbaum pflags = ZFS_ARCHIVE | ZFS_AV_MODIFIED; 8540a586ceaSMark Shellenbaum else 8550a586ceaSMark Shellenbaum pflags = 0; 856da6c28aaSamw 857fa9e4066Sahrens if (vap->va_type == VDIR) { 8580a586ceaSMark Shellenbaum size = 2; /* contents ("." and "..") */ 8590a586ceaSMark Shellenbaum links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1; 8600a586ceaSMark Shellenbaum } else { 8610a586ceaSMark Shellenbaum size = links = 0; 862fa9e4066Sahrens } 863fa9e4066Sahrens 8640a586ceaSMark Shellenbaum if (vap->va_type == VBLK || vap->va_type == VCHR) { 8650a586ceaSMark Shellenbaum rdev = zfs_expldev(vap->va_rdev); 8660a586ceaSMark Shellenbaum } 8670a586ceaSMark Shellenbaum 8680a586ceaSMark Shellenbaum parent = dzp->z_id; 8690a586ceaSMark Shellenbaum mode = acl_ids->z_mode; 870fa9e4066Sahrens if (flag & IS_XATTR) 8710a586ceaSMark Shellenbaum pflags |= ZFS_XATTR; 872fa9e4066Sahrens 8730a586ceaSMark Shellenbaum /* 8740a586ceaSMark Shellenbaum * No execs denied will be deterimed when zfs_mode_compute() is called. 8750a586ceaSMark Shellenbaum */ 8760a586ceaSMark Shellenbaum pflags |= acl_ids->z_aclp->z_hints & 8770a586ceaSMark Shellenbaum (ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|ZFS_ACL_AUTO_INHERIT| 8780a586ceaSMark Shellenbaum ZFS_ACL_DEFAULTED|ZFS_ACL_PROTECTED); 879fa9e4066Sahrens 8800a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, crtime); 8810a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, ctime); 882fa9e4066Sahrens 883fa9e4066Sahrens if (vap->va_mask & AT_ATIME) { 8840a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&vap->va_atime, atime); 885fa9e4066Sahrens } else { 8860a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, atime); 887fa9e4066Sahrens } 888fa9e4066Sahrens 889fa9e4066Sahrens if (vap->va_mask & AT_MTIME) { 8900a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&vap->va_mtime, mtime); 891fa9e4066Sahrens } else { 8920a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, mtime); 893fa9e4066Sahrens } 8940a586ceaSMark Shellenbaum 8950a586ceaSMark Shellenbaum /* Now add in all of the "SA" attributes */ 8960a586ceaSMark Shellenbaum VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED, 8970a586ceaSMark Shellenbaum &sa_hdl)); 8980a586ceaSMark Shellenbaum 8990a586ceaSMark Shellenbaum /* 9000a586ceaSMark Shellenbaum * Setup the array of attributes to be replaced/set on the new file 9010a586ceaSMark Shellenbaum * 9020a586ceaSMark Shellenbaum * order for DMU_OT_ZNODE is critical since it needs to be constructed 9030a586ceaSMark Shellenbaum * in the old znode_phys_t format. Don't change this ordering 9040a586ceaSMark Shellenbaum */ 9050a586ceaSMark Shellenbaum 9060a586ceaSMark Shellenbaum if (obj_type == DMU_OT_ZNODE) { 9070a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zfsvfs), 9080a586ceaSMark Shellenbaum NULL, &atime, 16); 9090a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zfsvfs), 9100a586ceaSMark Shellenbaum NULL, &mtime, 16); 9110a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zfsvfs), 9120a586ceaSMark Shellenbaum NULL, &ctime, 16); 9130a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zfsvfs), 9140a586ceaSMark Shellenbaum NULL, &crtime, 16); 9150a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zfsvfs), 9160a586ceaSMark Shellenbaum NULL, &gen, 8); 9170a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zfsvfs), 9180a586ceaSMark Shellenbaum NULL, &mode, 8); 9190a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zfsvfs), 9200a586ceaSMark Shellenbaum NULL, &size, 8); 9210a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zfsvfs), 9220a586ceaSMark Shellenbaum NULL, &parent, 8); 9230a586ceaSMark Shellenbaum } else { 9240a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zfsvfs), 9250a586ceaSMark Shellenbaum NULL, &mode, 8); 9260a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zfsvfs), 9270a586ceaSMark Shellenbaum NULL, &size, 8); 9280a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zfsvfs), 9290a586ceaSMark Shellenbaum NULL, &gen, 8); 9300a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zfsvfs), NULL, 9310a586ceaSMark Shellenbaum &acl_ids->z_fuid, 8); 9320a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zfsvfs), NULL, 9330a586ceaSMark Shellenbaum &acl_ids->z_fgid, 8); 9340a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zfsvfs), 9350a586ceaSMark Shellenbaum NULL, &parent, 8); 9360a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zfsvfs), 9370a586ceaSMark Shellenbaum NULL, &pflags, 8); 9380a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zfsvfs), 9390a586ceaSMark Shellenbaum NULL, &atime, 16); 9400a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zfsvfs), 9410a586ceaSMark Shellenbaum NULL, &mtime, 16); 9420a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zfsvfs), 9430a586ceaSMark Shellenbaum NULL, &ctime, 16); 9440a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zfsvfs), 9450a586ceaSMark Shellenbaum NULL, &crtime, 16); 9460a586ceaSMark Shellenbaum } 9470a586ceaSMark Shellenbaum 9480a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_LINKS(zfsvfs), NULL, &links, 8); 9490a586ceaSMark Shellenbaum 9500a586ceaSMark Shellenbaum if (obj_type == DMU_OT_ZNODE) { 9510a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_XATTR(zfsvfs), NULL, 9520a586ceaSMark Shellenbaum &empty_xattr, 8); 9530a586ceaSMark Shellenbaum } 9540a586ceaSMark Shellenbaum if (obj_type == DMU_OT_ZNODE || 9550a586ceaSMark Shellenbaum (vap->va_type == VBLK || vap->va_type == VCHR)) { 9560a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zfsvfs), 9570a586ceaSMark Shellenbaum NULL, &rdev, 8); 9580a586ceaSMark Shellenbaum 9590a586ceaSMark Shellenbaum } 9600a586ceaSMark Shellenbaum if (obj_type == DMU_OT_ZNODE) { 9610a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zfsvfs), 9620a586ceaSMark Shellenbaum NULL, &pflags, 8); 9630a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zfsvfs), NULL, 9640a586ceaSMark Shellenbaum &acl_ids->z_fuid, 8); 9650a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zfsvfs), NULL, 9660a586ceaSMark Shellenbaum &acl_ids->z_fgid, 8); 9670a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PAD(zfsvfs), NULL, pad, 9680a586ceaSMark Shellenbaum sizeof (uint64_t) * 4); 9690a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, 9700a586ceaSMark Shellenbaum &acl_phys, sizeof (zfs_acl_phys_t)); 9710a586ceaSMark Shellenbaum } else if (acl_ids->z_aclp->z_version >= ZFS_ACL_VERSION_FUID) { 9720a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_COUNT(zfsvfs), NULL, 9730a586ceaSMark Shellenbaum &acl_ids->z_aclp->z_acl_count, 8); 9740a586ceaSMark Shellenbaum locate.cb_aclp = acl_ids->z_aclp; 9750a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_ACES(zfsvfs), 9760a586ceaSMark Shellenbaum zfs_acl_data_locator, &locate, 9770a586ceaSMark Shellenbaum acl_ids->z_aclp->z_acl_bytes); 97827dd1e87SMark Shellenbaum mode = zfs_mode_compute(mode, acl_ids->z_aclp, &pflags, 97927dd1e87SMark Shellenbaum acl_ids->z_fuid, acl_ids->z_fgid); 9800a586ceaSMark Shellenbaum } 9810a586ceaSMark Shellenbaum 9820a586ceaSMark Shellenbaum VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0); 9830a586ceaSMark Shellenbaum 984874395d5Smaybee if (!(flag & IS_ROOT_NODE)) { 9850a586ceaSMark Shellenbaum *zpp = zfs_znode_alloc(zfsvfs, db, 0, obj_type, sa_hdl); 9860a586ceaSMark Shellenbaum ASSERT(*zpp != NULL); 987874395d5Smaybee } else { 988874395d5Smaybee /* 989874395d5Smaybee * If we are creating the root node, the "parent" we 990874395d5Smaybee * passed in is the znode for the root. 991874395d5Smaybee */ 992874395d5Smaybee *zpp = dzp; 99359e7834dSMark Shellenbaum 9940a586ceaSMark Shellenbaum (*zpp)->z_sa_hdl = sa_hdl; 9950a586ceaSMark Shellenbaum } 9960a586ceaSMark Shellenbaum 9970a586ceaSMark Shellenbaum (*zpp)->z_pflags = pflags; 9980a586ceaSMark Shellenbaum (*zpp)->z_mode = mode; 9990a586ceaSMark Shellenbaum 10008f2529deSMark Shellenbaum if (vap->va_mask & AT_XVATTR) 10018f2529deSMark Shellenbaum zfs_xvattr_set(*zpp, (xvattr_t *)vap, tx); 10028f2529deSMark Shellenbaum 10030a586ceaSMark Shellenbaum if (obj_type == DMU_OT_ZNODE || 10040a586ceaSMark Shellenbaum acl_ids->z_aclp->z_version < ZFS_ACL_VERSION_FUID) { 100543466aaeSMax Grossman VERIFY0(zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx)); 10060a586ceaSMark Shellenbaum } 100759e7834dSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); 1008fa9e4066Sahrens } 1009fa9e4066Sahrens 10100a586ceaSMark Shellenbaum /* 1011f7170741SWill Andrews * Update in-core attributes. It is assumed the caller will be doing an 1012f7170741SWill Andrews * sa_bulk_update to push the changes out. 10130a586ceaSMark Shellenbaum */ 1014da6c28aaSamw void 10150a586ceaSMark Shellenbaum zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) 1016da6c28aaSamw { 1017da6c28aaSamw xoptattr_t *xoap; 1018da6c28aaSamw 1019da6c28aaSamw xoap = xva_getxoptattr(xvap); 1020da6c28aaSamw ASSERT(xoap); 1021da6c28aaSamw 1022da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { 10230a586ceaSMark Shellenbaum uint64_t times[2]; 10240a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&xoap->xoa_createtime, times); 10250a586ceaSMark Shellenbaum (void) sa_update(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), 10260a586ceaSMark Shellenbaum ×, sizeof (times), tx); 1027da6c28aaSamw XVA_SET_RTN(xvap, XAT_CREATETIME); 1028da6c28aaSamw } 1029da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { 10300a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_READONLY, xoap->xoa_readonly, 10310a586ceaSMark Shellenbaum zp->z_pflags, tx); 1032da6c28aaSamw XVA_SET_RTN(xvap, XAT_READONLY); 1033da6c28aaSamw } 1034da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { 10350a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_HIDDEN, xoap->xoa_hidden, 10360a586ceaSMark Shellenbaum zp->z_pflags, tx); 1037da6c28aaSamw XVA_SET_RTN(xvap, XAT_HIDDEN); 1038da6c28aaSamw } 1039da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { 10400a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_SYSTEM, xoap->xoa_system, 10410a586ceaSMark Shellenbaum zp->z_pflags, tx); 1042da6c28aaSamw XVA_SET_RTN(xvap, XAT_SYSTEM); 1043da6c28aaSamw } 1044da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { 10450a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_ARCHIVE, xoap->xoa_archive, 10460a586ceaSMark Shellenbaum zp->z_pflags, tx); 1047da6c28aaSamw XVA_SET_RTN(xvap, XAT_ARCHIVE); 1048da6c28aaSamw } 1049da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) { 10500a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_IMMUTABLE, xoap->xoa_immutable, 10510a586ceaSMark Shellenbaum zp->z_pflags, tx); 1052da6c28aaSamw XVA_SET_RTN(xvap, XAT_IMMUTABLE); 1053da6c28aaSamw } 1054da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { 10550a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_NOUNLINK, xoap->xoa_nounlink, 10560a586ceaSMark Shellenbaum zp->z_pflags, tx); 1057da6c28aaSamw XVA_SET_RTN(xvap, XAT_NOUNLINK); 1058da6c28aaSamw } 1059da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) { 10600a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_APPENDONLY, xoap->xoa_appendonly, 10610a586ceaSMark Shellenbaum zp->z_pflags, tx); 1062da6c28aaSamw XVA_SET_RTN(xvap, XAT_APPENDONLY); 1063da6c28aaSamw } 1064da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { 10650a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_NODUMP, xoap->xoa_nodump, 10660a586ceaSMark Shellenbaum zp->z_pflags, tx); 1067da6c28aaSamw XVA_SET_RTN(xvap, XAT_NODUMP); 1068da6c28aaSamw } 1069da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) { 10700a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_OPAQUE, xoap->xoa_opaque, 10710a586ceaSMark Shellenbaum zp->z_pflags, tx); 1072da6c28aaSamw XVA_SET_RTN(xvap, XAT_OPAQUE); 1073da6c28aaSamw } 1074da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { 1075da6c28aaSamw ZFS_ATTR_SET(zp, ZFS_AV_QUARANTINED, 10760a586ceaSMark Shellenbaum xoap->xoa_av_quarantined, zp->z_pflags, tx); 1077da6c28aaSamw XVA_SET_RTN(xvap, XAT_AV_QUARANTINED); 1078da6c28aaSamw } 1079da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) { 10800a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_AV_MODIFIED, xoap->xoa_av_modified, 10810a586ceaSMark Shellenbaum zp->z_pflags, tx); 1082da6c28aaSamw XVA_SET_RTN(xvap, XAT_AV_MODIFIED); 1083da6c28aaSamw } 1084da6c28aaSamw if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { 10850a586ceaSMark Shellenbaum zfs_sa_set_scanstamp(zp, xvap, tx); 1086da6c28aaSamw XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP); 1087da6c28aaSamw } 10887a286c47SDai Ngo if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) { 10890a586ceaSMark Shellenbaum ZFS_ATTR_SET(zp, ZFS_REPARSE, xoap->xoa_reparse, 10900a586ceaSMark Shellenbaum zp->z_pflags, tx); 10917a286c47SDai Ngo XVA_SET_RTN(xvap, XAT_REPARSE); 10927a286c47SDai Ngo } 1093fd9ee8b5Sjoyce mcintosh if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) { 1094fd9ee8b5Sjoyce mcintosh ZFS_ATTR_SET(zp, ZFS_OFFLINE, xoap->xoa_offline, 1095fd9ee8b5Sjoyce mcintosh zp->z_pflags, tx); 1096fd9ee8b5Sjoyce mcintosh XVA_SET_RTN(xvap, XAT_OFFLINE); 1097fd9ee8b5Sjoyce mcintosh } 1098fd9ee8b5Sjoyce mcintosh if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) { 1099fd9ee8b5Sjoyce mcintosh ZFS_ATTR_SET(zp, ZFS_SPARSE, xoap->xoa_sparse, 1100fd9ee8b5Sjoyce mcintosh zp->z_pflags, tx); 1101fd9ee8b5Sjoyce mcintosh XVA_SET_RTN(xvap, XAT_SPARSE); 1102fd9ee8b5Sjoyce mcintosh } 1103da6c28aaSamw } 1104da6c28aaSamw 1105fa9e4066Sahrens int 1106fa9e4066Sahrens zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) 1107fa9e4066Sahrens { 1108fa9e4066Sahrens dmu_object_info_t doi; 1109fa9e4066Sahrens dmu_buf_t *db; 1110fa9e4066Sahrens znode_t *zp; 1111ea8dc4b6Seschrock int err; 11120a586ceaSMark Shellenbaum sa_handle_t *hdl; 1113fa9e4066Sahrens 1114fa9e4066Sahrens *zpp = NULL; 1115fa9e4066Sahrens 1116fa9e4066Sahrens ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); 1117fa9e4066Sahrens 11180a586ceaSMark Shellenbaum err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); 1119ea8dc4b6Seschrock if (err) { 1120fa9e4066Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1121ea8dc4b6Seschrock return (err); 1122fa9e4066Sahrens } 1123fa9e4066Sahrens 1124fa9e4066Sahrens dmu_object_info_from_db(db, &doi); 11250a586ceaSMark Shellenbaum if (doi.doi_bonus_type != DMU_OT_SA && 11260a586ceaSMark Shellenbaum (doi.doi_bonus_type != DMU_OT_ZNODE || 11270a586ceaSMark Shellenbaum (doi.doi_bonus_type == DMU_OT_ZNODE && 11280a586ceaSMark Shellenbaum doi.doi_bonus_size < sizeof (znode_phys_t)))) { 11290a586ceaSMark Shellenbaum sa_buf_rele(db, NULL); 1130fa9e4066Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1131be6fd75aSMatthew Ahrens return (SET_ERROR(EINVAL)); 1132fa9e4066Sahrens } 1133fa9e4066Sahrens 11340a586ceaSMark Shellenbaum hdl = dmu_buf_get_user(db); 11350a586ceaSMark Shellenbaum if (hdl != NULL) { 11360a586ceaSMark Shellenbaum zp = sa_get_userdata(hdl); 11370a586ceaSMark Shellenbaum 1138fa9e4066Sahrens 11394ccbb6e7Sahrens /* 11400a586ceaSMark Shellenbaum * Since "SA" does immediate eviction we 11410a586ceaSMark Shellenbaum * should never find a sa handle that doesn't 11420a586ceaSMark Shellenbaum * know about the znode. 11434ccbb6e7Sahrens */ 11440a586ceaSMark Shellenbaum 11450a586ceaSMark Shellenbaum ASSERT3P(zp, !=, NULL); 11460a586ceaSMark Shellenbaum 11470a586ceaSMark Shellenbaum mutex_enter(&zp->z_lock); 1148fa9e4066Sahrens ASSERT3U(zp->z_id, ==, obj_num); 1149893a6d32Sahrens if (zp->z_unlinked) { 1150be6fd75aSMatthew Ahrens err = SET_ERROR(ENOENT); 1151fa9e4066Sahrens } else { 1152fa9e4066Sahrens VN_HOLD(ZTOV(zp)); 11534ccbb6e7Sahrens *zpp = zp; 11544ccbb6e7Sahrens err = 0; 11554ccbb6e7Sahrens } 1156fa9e4066Sahrens mutex_exit(&zp->z_lock); 1157eaef6a96SRichard Yao sa_buf_rele(db, NULL); 1158ea8dc4b6Seschrock ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 11594ccbb6e7Sahrens return (err); 1160fa9e4066Sahrens } 1161fa9e4066Sahrens 1162fa9e4066Sahrens /* 1163fa9e4066Sahrens * Not found create new znode/vnode 116459e7834dSMark Shellenbaum * but only if file exists. 116559e7834dSMark Shellenbaum * 116659e7834dSMark Shellenbaum * There is a small window where zfs_vget() could 116759e7834dSMark Shellenbaum * find this object while a file create is still in 11680a586ceaSMark Shellenbaum * progress. This is checked for in zfs_znode_alloc() 11690a586ceaSMark Shellenbaum * 11700a586ceaSMark Shellenbaum * if zfs_znode_alloc() fails it will drop the hold on the 11710a586ceaSMark Shellenbaum * bonus buffer. 1172fa9e4066Sahrens */ 11730a586ceaSMark Shellenbaum zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size, 11740a586ceaSMark Shellenbaum doi.doi_bonus_type, NULL); 11750a586ceaSMark Shellenbaum if (zp == NULL) { 1176be6fd75aSMatthew Ahrens err = SET_ERROR(ENOENT); 11770a586ceaSMark Shellenbaum } else { 1178*9d7a20afSArne Jansen if (zp->z_links == 0) 1179*9d7a20afSArne Jansen zp->z_unlinked = B_TRUE; 11800a586ceaSMark Shellenbaum *zpp = zp; 118159e7834dSMark Shellenbaum } 118259e7834dSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 118359e7834dSMark Shellenbaum return (err); 1184fa9e4066Sahrens } 1185fa9e4066Sahrens 1186f18faf3fSek110237 int 1187f18faf3fSek110237 zfs_rezget(znode_t *zp) 1188f18faf3fSek110237 { 1189f18faf3fSek110237 zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1190f18faf3fSek110237 dmu_object_info_t doi; 1191f18faf3fSek110237 dmu_buf_t *db; 1192f18faf3fSek110237 uint64_t obj_num = zp->z_id; 11930a586ceaSMark Shellenbaum uint64_t mode; 11940a586ceaSMark Shellenbaum sa_bulk_attr_t bulk[8]; 1195f18faf3fSek110237 int err; 11960a586ceaSMark Shellenbaum int count = 0; 11970a586ceaSMark Shellenbaum uint64_t gen; 1198f18faf3fSek110237 1199f18faf3fSek110237 ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); 1200f18faf3fSek110237 12016638ae1dSMark Shellenbaum mutex_enter(&zp->z_acl_lock); 12026638ae1dSMark Shellenbaum if (zp->z_acl_cached) { 12036638ae1dSMark Shellenbaum zfs_acl_free(zp->z_acl_cached); 12046638ae1dSMark Shellenbaum zp->z_acl_cached = NULL; 12056638ae1dSMark Shellenbaum } 12066638ae1dSMark Shellenbaum 12070a586ceaSMark Shellenbaum mutex_exit(&zp->z_acl_lock); 12080a586ceaSMark Shellenbaum ASSERT(zp->z_sa_hdl == NULL); 12090a586ceaSMark Shellenbaum err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); 12100a586ceaSMark Shellenbaum if (err) { 12110a586ceaSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 12120a586ceaSMark Shellenbaum return (err); 12130a586ceaSMark Shellenbaum } 12140a586ceaSMark Shellenbaum 12150a586ceaSMark Shellenbaum dmu_object_info_from_db(db, &doi); 12160a586ceaSMark Shellenbaum if (doi.doi_bonus_type != DMU_OT_SA && 12170a586ceaSMark Shellenbaum (doi.doi_bonus_type != DMU_OT_ZNODE || 12180a586ceaSMark Shellenbaum (doi.doi_bonus_type == DMU_OT_ZNODE && 12190a586ceaSMark Shellenbaum doi.doi_bonus_size < sizeof (znode_phys_t)))) { 12200a586ceaSMark Shellenbaum sa_buf_rele(db, NULL); 12210a586ceaSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1222be6fd75aSMatthew Ahrens return (SET_ERROR(EINVAL)); 12230a586ceaSMark Shellenbaum } 12240a586ceaSMark Shellenbaum 12250a586ceaSMark Shellenbaum zfs_znode_sa_init(zfsvfs, zp, db, doi.doi_bonus_type, NULL); 12260a586ceaSMark Shellenbaum 12270a586ceaSMark Shellenbaum /* reload cached values */ 12280a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, 12290a586ceaSMark Shellenbaum &gen, sizeof (gen)); 12300a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, 12310a586ceaSMark Shellenbaum &zp->z_size, sizeof (zp->z_size)); 12320a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, 12330a586ceaSMark Shellenbaum &zp->z_links, sizeof (zp->z_links)); 12340a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, 12350a586ceaSMark Shellenbaum &zp->z_pflags, sizeof (zp->z_pflags)); 12360a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, 12370a586ceaSMark Shellenbaum &zp->z_atime, sizeof (zp->z_atime)); 12380a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, 1239f1696b23SMark Shellenbaum &zp->z_uid, sizeof (zp->z_uid)); 12400a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, 1241f1696b23SMark Shellenbaum &zp->z_gid, sizeof (zp->z_gid)); 12420a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, 12430a586ceaSMark Shellenbaum &mode, sizeof (mode)); 12440a586ceaSMark Shellenbaum 12450a586ceaSMark Shellenbaum if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) { 12460a586ceaSMark Shellenbaum zfs_znode_dmu_fini(zp); 12470a586ceaSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1248be6fd75aSMatthew Ahrens return (SET_ERROR(EIO)); 12490a586ceaSMark Shellenbaum } 12500a586ceaSMark Shellenbaum 12511412a1a2SMark Shellenbaum zp->z_mode = mode; 12521412a1a2SMark Shellenbaum 12530a586ceaSMark Shellenbaum if (gen != zp->z_gen) { 12540a586ceaSMark Shellenbaum zfs_znode_dmu_fini(zp); 12550a586ceaSMark Shellenbaum ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1256be6fd75aSMatthew Ahrens return (SET_ERROR(EIO)); 12570a586ceaSMark Shellenbaum } 12580a586ceaSMark Shellenbaum 12590a586ceaSMark Shellenbaum zp->z_unlinked = (zp->z_links == 0); 12606166ad1cSek110237 zp->z_blksz = doi.doi_data_block_size; 1261f18faf3fSek110237 1262f18faf3fSek110237 ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); 1263f18faf3fSek110237 1264f18faf3fSek110237 return (0); 1265f18faf3fSek110237 } 1266f18faf3fSek110237 1267fa9e4066Sahrens void 1268fa9e4066Sahrens zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) 1269fa9e4066Sahrens { 1270fa9e4066Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1271cdb0ab79Smaybee objset_t *os = zfsvfs->z_os; 12724ccbb6e7Sahrens uint64_t obj = zp->z_id; 12731412a1a2SMark Shellenbaum uint64_t acl_obj = zfs_external_acl(zp); 1274fa9e4066Sahrens 12754ccbb6e7Sahrens ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); 12761412a1a2SMark Shellenbaum if (acl_obj) { 12771412a1a2SMark Shellenbaum VERIFY(!zp->z_is_sa); 1278cdb0ab79Smaybee VERIFY(0 == dmu_object_free(os, acl_obj, tx)); 12791412a1a2SMark Shellenbaum } 1280cdb0ab79Smaybee VERIFY(0 == dmu_object_free(os, obj, tx)); 12814ccbb6e7Sahrens zfs_znode_dmu_fini(zp); 12824ccbb6e7Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); 1283874395d5Smaybee zfs_znode_free(zp); 1284fa9e4066Sahrens } 1285fa9e4066Sahrens 1286fa9e4066Sahrens void 1287fa9e4066Sahrens zfs_zinactive(znode_t *zp) 1288fa9e4066Sahrens { 1289fa9e4066Sahrens vnode_t *vp = ZTOV(zp); 1290fa9e4066Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1291fa9e4066Sahrens uint64_t z_id = zp->z_id; 1292fa9e4066Sahrens 12930a586ceaSMark Shellenbaum ASSERT(zp->z_sa_hdl); 1294fa9e4066Sahrens 1295fa9e4066Sahrens /* 1296fa9e4066Sahrens * Don't allow a zfs_zget() while were trying to release this znode 1297fa9e4066Sahrens */ 1298fa9e4066Sahrens ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id); 1299fa9e4066Sahrens 1300fa9e4066Sahrens mutex_enter(&zp->z_lock); 1301fa9e4066Sahrens mutex_enter(&vp->v_lock); 1302fa9e4066Sahrens vp->v_count--; 1303fa9e4066Sahrens if (vp->v_count > 0 || vn_has_cached_data(vp)) { 1304fa9e4066Sahrens /* 1305fa9e4066Sahrens * If the hold count is greater than zero, somebody has 1306fa9e4066Sahrens * obtained a new reference on this znode while we were 1307fa9e4066Sahrens * processing it here, so we are done. If we still have 1308fa9e4066Sahrens * mapped pages then we are also done, since we don't 1309fa9e4066Sahrens * want to inactivate the znode until the pages get pushed. 1310fa9e4066Sahrens * 1311fa9e4066Sahrens * XXX - if vn_has_cached_data(vp) is true, but count == 0, 1312fa9e4066Sahrens * this seems like it would leave the znode hanging with 1313fa9e4066Sahrens * no chance to go inactive... 1314fa9e4066Sahrens */ 1315fa9e4066Sahrens mutex_exit(&vp->v_lock); 1316fa9e4066Sahrens mutex_exit(&zp->z_lock); 1317fa9e4066Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); 1318fa9e4066Sahrens return; 1319fa9e4066Sahrens } 1320fa9e4066Sahrens mutex_exit(&vp->v_lock); 1321fa9e4066Sahrens 1322fa9e4066Sahrens /* 1323fa9e4066Sahrens * If this was the last reference to a file with no links, 1324fa9e4066Sahrens * remove the file from the file system. 1325fa9e4066Sahrens */ 1326893a6d32Sahrens if (zp->z_unlinked) { 1327fa9e4066Sahrens mutex_exit(&zp->z_lock); 1328fa9e4066Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); 1329fa9e4066Sahrens zfs_rmnode(zp); 1330fa9e4066Sahrens return; 1331fa9e4066Sahrens } 13320a586ceaSMark Shellenbaum 1333fa9e4066Sahrens mutex_exit(&zp->z_lock); 13344ccbb6e7Sahrens zfs_znode_dmu_fini(zp); 1335fa9e4066Sahrens ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); 1336874395d5Smaybee zfs_znode_free(zp); 1337fa9e4066Sahrens } 1338fa9e4066Sahrens 1339fa9e4066Sahrens void 1340fa9e4066Sahrens zfs_znode_free(znode_t *zp) 1341fa9e4066Sahrens { 1342fa9e4066Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1343fa9e4066Sahrens 1344874395d5Smaybee vn_invalid(ZTOV(zp)); 1345874395d5Smaybee 1346b5fca8f8Stomee ASSERT(ZTOV(zp)->v_count == 0); 1347b5fca8f8Stomee 1348fa9e4066Sahrens mutex_enter(&zfsvfs->z_znodes_lock); 1349b5fca8f8Stomee POINTER_INVALIDATE(&zp->z_zfsvfs); 1350fa9e4066Sahrens list_remove(&zfsvfs->z_all_znodes, zp); 1351fa9e4066Sahrens mutex_exit(&zfsvfs->z_znodes_lock); 1352fa9e4066Sahrens 1353d47621a4STim Haley if (zp->z_acl_cached) { 1354d47621a4STim Haley zfs_acl_free(zp->z_acl_cached); 1355d47621a4STim Haley zp->z_acl_cached = NULL; 1356d47621a4STim Haley } 1357d47621a4STim Haley 1358fa9e4066Sahrens kmem_cache_free(znode_cache, zp); 1359874395d5Smaybee 1360874395d5Smaybee VFS_RELE(zfsvfs->z_vfs); 1361fa9e4066Sahrens } 1362fa9e4066Sahrens 1363fa9e4066Sahrens void 13640a586ceaSMark Shellenbaum zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2], 13650a586ceaSMark Shellenbaum uint64_t ctime[2], boolean_t have_tx) 1366fa9e4066Sahrens { 1367fa9e4066Sahrens timestruc_t now; 1368fa9e4066Sahrens 1369fa9e4066Sahrens gethrestime(&now); 1370fa9e4066Sahrens 13710a586ceaSMark Shellenbaum if (have_tx) { /* will sa_bulk_update happen really soon? */ 1372fa9e4066Sahrens zp->z_atime_dirty = 0; 1373fa9e4066Sahrens zp->z_seq++; 1374fa9e4066Sahrens } else { 1375fa9e4066Sahrens zp->z_atime_dirty = 1; 1376fa9e4066Sahrens } 1377fa9e4066Sahrens 13780a586ceaSMark Shellenbaum if (flag & AT_ATIME) { 13790a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, zp->z_atime); 13800a586ceaSMark Shellenbaum } 1381fa9e4066Sahrens 1382da6c28aaSamw if (flag & AT_MTIME) { 13830a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, mtime); 13840a586ceaSMark Shellenbaum if (zp->z_zfsvfs->z_use_fuids) { 13850a586ceaSMark Shellenbaum zp->z_pflags |= (ZFS_ARCHIVE | 13860a586ceaSMark Shellenbaum ZFS_AV_MODIFIED); 13870a586ceaSMark Shellenbaum } 1388da6c28aaSamw } 1389fa9e4066Sahrens 1390da6c28aaSamw if (flag & AT_CTIME) { 13910a586ceaSMark Shellenbaum ZFS_TIME_ENCODE(&now, ctime); 1392da6c28aaSamw if (zp->z_zfsvfs->z_use_fuids) 13930a586ceaSMark Shellenbaum zp->z_pflags |= ZFS_ARCHIVE; 1394da6c28aaSamw } 1395fa9e4066Sahrens } 1396fa9e4066Sahrens 1397fa9e4066Sahrens /* 1398104e2ed7Sperrin * Grow the block size for a file. 1399fa9e4066Sahrens * 1400fa9e4066Sahrens * IN: zp - znode of file to free data in. 1401fa9e4066Sahrens * size - requested block size 1402fa9e4066Sahrens * tx - open transaction. 1403fa9e4066Sahrens * 1404fa9e4066Sahrens * NOTE: this function assumes that the znode is write locked. 1405fa9e4066Sahrens */ 1406104e2ed7Sperrin void 1407fa9e4066Sahrens zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) 1408fa9e4066Sahrens { 1409fa9e4066Sahrens int error; 1410fa9e4066Sahrens u_longlong_t dummy; 1411fa9e4066Sahrens 1412fa9e4066Sahrens if (size <= zp->z_blksz) 1413104e2ed7Sperrin return; 1414fa9e4066Sahrens /* 1415fa9e4066Sahrens * If the file size is already greater than the current blocksize, 1416fa9e4066Sahrens * we will not grow. If there is more than one block in a file, 1417fa9e4066Sahrens * the blocksize cannot change. 1418fa9e4066Sahrens */ 14190a586ceaSMark Shellenbaum if (zp->z_blksz && zp->z_size > zp->z_blksz) 1420104e2ed7Sperrin return; 1421fa9e4066Sahrens 1422fa9e4066Sahrens error = dmu_object_set_blocksize(zp->z_zfsvfs->z_os, zp->z_id, 1423fa9e4066Sahrens size, 0, tx); 14240a586ceaSMark Shellenbaum 1425fa9e4066Sahrens if (error == ENOTSUP) 1426104e2ed7Sperrin return; 1427fb09f5aaSMadhav Suresh ASSERT0(error); 1428fa9e4066Sahrens 1429fa9e4066Sahrens /* What blocksize did we actually get? */ 14300a586ceaSMark Shellenbaum dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy); 1431fa9e4066Sahrens } 1432fa9e4066Sahrens 1433fa9e4066Sahrens /* 1434fa9e4066Sahrens * This is a dummy interface used when pvn_vplist_dirty() should *not* 1435fa9e4066Sahrens * be calling back into the fs for a putpage(). E.g.: when truncating 1436fa9e4066Sahrens * a file, the pages being "thrown away* don't need to be written out. 1437fa9e4066Sahrens */ 1438fa9e4066Sahrens /* ARGSUSED */ 1439fa9e4066Sahrens static int 1440fa9e4066Sahrens zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, 1441fa9e4066Sahrens int flags, cred_t *cr) 1442fa9e4066Sahrens { 1443fa9e4066Sahrens ASSERT(0); 1444fa9e4066Sahrens return (0); 1445fa9e4066Sahrens } 1446fa9e4066Sahrens 1447fa9e4066Sahrens /* 1448cdb0ab79Smaybee * Increase the file length 1449fa9e4066Sahrens * 1450fa9e4066Sahrens * IN: zp - znode of file to free data in. 1451cdb0ab79Smaybee * end - new end-of-file 1452fa9e4066Sahrens * 1453f7170741SWill Andrews * RETURN: 0 on success, error code on failure 1454cdeb8ec5SSimon Klinkert * 1455cdeb8ec5SSimon Klinkert * Assumption: File is already range-locked for changing zp_size 1456fa9e4066Sahrens */ 1457cdb0ab79Smaybee static int 1458cdb0ab79Smaybee zfs_extend(znode_t *zp, uint64_t end) 1459fa9e4066Sahrens { 14605730cc9aSmaybee zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1461cdb0ab79Smaybee dmu_tx_t *tx; 1462cdb0ab79Smaybee uint64_t newblksz; 1463104e2ed7Sperrin int error; 1464fa9e4066Sahrens 1465fa9e4066Sahrens /* 1466fa9e4066Sahrens * Nothing to do if file already at desired length. 1467fa9e4066Sahrens */ 1468cdeb8ec5SSimon Klinkert if (end <= zp->z_size) 1469fa9e4066Sahrens return (0); 1470cdeb8ec5SSimon Klinkert 14715730cc9aSmaybee tx = dmu_tx_create(zfsvfs->z_os); 14720a586ceaSMark Shellenbaum dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); 14730a586ceaSMark Shellenbaum zfs_sa_upgrade_txholds(tx, zp); 1474cdb0ab79Smaybee if (end > zp->z_blksz && 14755730cc9aSmaybee (!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) { 1476fa9e4066Sahrens /* 1477fa9e4066Sahrens * We are growing the file past the current block size. 1478fa9e4066Sahrens */ 1479fa9e4066Sahrens if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { 1480b5152584SMatthew Ahrens /* 1481b5152584SMatthew Ahrens * File's blocksize is already larger than the 1482b5152584SMatthew Ahrens * "recordsize" property. Only let it grow to 1483b5152584SMatthew Ahrens * the next power of 2. 1484b5152584SMatthew Ahrens */ 1485fa9e4066Sahrens ASSERT(!ISP2(zp->z_blksz)); 1486b5152584SMatthew Ahrens newblksz = MIN(end, 1 << highbit64(zp->z_blksz)); 1487fa9e4066Sahrens } else { 1488cdb0ab79Smaybee newblksz = MIN(end, zp->z_zfsvfs->z_max_blksz); 1489fa9e4066Sahrens } 1490cdb0ab79Smaybee dmu_tx_hold_write(tx, zp->z_id, 0, newblksz); 1491cdb0ab79Smaybee } else { 1492cdb0ab79Smaybee newblksz = 0; 1493fa9e4066Sahrens } 14945730cc9aSmaybee 1495e722410cSMatthew Ahrens error = dmu_tx_assign(tx, TXG_WAIT); 14965730cc9aSmaybee if (error) { 1497cdb0ab79Smaybee dmu_tx_abort(tx); 14985730cc9aSmaybee return (error); 14995730cc9aSmaybee } 15005730cc9aSmaybee 1501cdb0ab79Smaybee if (newblksz) 1502cdb0ab79Smaybee zfs_grow_blocksize(zp, newblksz, tx); 15035730cc9aSmaybee 15040a586ceaSMark Shellenbaum zp->z_size = end; 15050a586ceaSMark Shellenbaum 15060a586ceaSMark Shellenbaum VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zp->z_zfsvfs), 15070a586ceaSMark Shellenbaum &zp->z_size, sizeof (zp->z_size), tx)); 1508fa9e4066Sahrens 15095730cc9aSmaybee dmu_tx_commit(tx); 15105730cc9aSmaybee 1511cdb0ab79Smaybee return (0); 1512cdb0ab79Smaybee } 1513cdb0ab79Smaybee 1514cdb0ab79Smaybee /* 1515cdb0ab79Smaybee * Free space in a file. 1516cdb0ab79Smaybee * 1517cdb0ab79Smaybee * IN: zp - znode of file to free data in. 1518cdb0ab79Smaybee * off - start of section to free. 1519cdb0ab79Smaybee * len - length of section to free. 1520cdb0ab79Smaybee * 1521f7170741SWill Andrews * RETURN: 0 on success, error code on failure 1522cdeb8ec5SSimon Klinkert * 1523cdeb8ec5SSimon Klinkert * Assumption: file is already range-locked for changing zp_size 1524cdb0ab79Smaybee */ 1525cdb0ab79Smaybee static int 1526cdb0ab79Smaybee zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) 1527cdb0ab79Smaybee { 1528cdb0ab79Smaybee zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1529cdb0ab79Smaybee int error; 1530cdb0ab79Smaybee 1531cdb0ab79Smaybee /* 1532cdb0ab79Smaybee * Nothing to do if file already at desired length. 1533cdb0ab79Smaybee */ 1534cdeb8ec5SSimon Klinkert if (off >= zp->z_size) 1535cdb0ab79Smaybee return (0); 1536cdb0ab79Smaybee 15370a586ceaSMark Shellenbaum if (off + len > zp->z_size) 15380a586ceaSMark Shellenbaum len = zp->z_size - off; 1539cdb0ab79Smaybee 1540cdb0ab79Smaybee error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, off, len); 1541cdb0ab79Smaybee 1542cdb0ab79Smaybee return (error); 1543cdb0ab79Smaybee } 1544cdb0ab79Smaybee 1545cdb0ab79Smaybee /* 1546cdb0ab79Smaybee * Truncate a file 1547cdb0ab79Smaybee * 1548cdb0ab79Smaybee * IN: zp - znode of file to free data in. 1549cdb0ab79Smaybee * end - new end-of-file. 1550cdb0ab79Smaybee * 1551f7170741SWill Andrews * RETURN: 0 on success, error code on failure 1552cdeb8ec5SSimon Klinkert * 1553cdeb8ec5SSimon Klinkert * Assumption: file is already range-locked for changing zp_size 1554cdb0ab79Smaybee */ 1555cdb0ab79Smaybee static int 1556cdb0ab79Smaybee zfs_trunc(znode_t *zp, uint64_t end) 1557cdb0ab79Smaybee { 1558cdb0ab79Smaybee zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1559cdb0ab79Smaybee vnode_t *vp = ZTOV(zp); 1560cdb0ab79Smaybee dmu_tx_t *tx; 1561cdb0ab79Smaybee int error; 1562fd9ee8b5Sjoyce mcintosh sa_bulk_attr_t bulk[2]; 1563fd9ee8b5Sjoyce mcintosh int count = 0; 1564cdb0ab79Smaybee 1565cdb0ab79Smaybee /* 1566cdb0ab79Smaybee * Nothing to do if file already at desired length. 1567cdb0ab79Smaybee */ 1568cdeb8ec5SSimon Klinkert if (end >= zp->z_size) 1569cdb0ab79Smaybee return (0); 1570cdb0ab79Smaybee 1571cdb0ab79Smaybee error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end, -1); 1572cdeb8ec5SSimon Klinkert if (error) 1573cdb0ab79Smaybee return (error); 1574cdeb8ec5SSimon Klinkert 1575cdb0ab79Smaybee tx = dmu_tx_create(zfsvfs->z_os); 15760a586ceaSMark Shellenbaum dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); 15770a586ceaSMark Shellenbaum zfs_sa_upgrade_txholds(tx, zp); 15784bb73804SMatthew Ahrens dmu_tx_mark_netfree(tx); 1579e722410cSMatthew Ahrens error = dmu_tx_assign(tx, TXG_WAIT); 1580cdb0ab79Smaybee if (error) { 1581cdb0ab79Smaybee dmu_tx_abort(tx); 1582cdb0ab79Smaybee return (error); 1583cdb0ab79Smaybee } 1584cdb0ab79Smaybee 15850a586ceaSMark Shellenbaum zp->z_size = end; 1586fd9ee8b5Sjoyce mcintosh SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), 1587fd9ee8b5Sjoyce mcintosh NULL, &zp->z_size, sizeof (zp->z_size)); 15880a586ceaSMark Shellenbaum 1589fd9ee8b5Sjoyce mcintosh if (end == 0) { 1590fd9ee8b5Sjoyce mcintosh zp->z_pflags &= ~ZFS_SPARSE; 1591fd9ee8b5Sjoyce mcintosh SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), 1592fd9ee8b5Sjoyce mcintosh NULL, &zp->z_pflags, 8); 1593fd9ee8b5Sjoyce mcintosh } 1594fd9ee8b5Sjoyce mcintosh VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0); 1595cdb0ab79Smaybee 1596cdb0ab79Smaybee dmu_tx_commit(tx); 1597cdb0ab79Smaybee 15985730cc9aSmaybee /* 15995730cc9aSmaybee * Clear any mapped pages in the truncated region. This has to 16005730cc9aSmaybee * happen outside of the transaction to avoid the possibility of 16015730cc9aSmaybee * a deadlock with someone trying to push a page that we are 16025730cc9aSmaybee * about to invalidate. 16035730cc9aSmaybee */ 1604cdb0ab79Smaybee if (vn_has_cached_data(vp)) { 16055730cc9aSmaybee page_t *pp; 1606cdb0ab79Smaybee uint64_t start = end & PAGEMASK; 1607cdb0ab79Smaybee int poff = end & PAGEOFFSET; 16085730cc9aSmaybee 16095730cc9aSmaybee if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) { 16105730cc9aSmaybee /* 16115730cc9aSmaybee * We need to zero a partial page. 16125730cc9aSmaybee */ 16135730cc9aSmaybee pagezero(pp, poff, PAGESIZE - poff); 16145730cc9aSmaybee start += PAGESIZE; 16155730cc9aSmaybee page_unlock(pp); 16165730cc9aSmaybee } 16175730cc9aSmaybee error = pvn_vplist_dirty(vp, start, zfs_no_putpage, 16185730cc9aSmaybee B_INVAL | B_TRUNC, NULL); 16195730cc9aSmaybee ASSERT(error == 0); 16205730cc9aSmaybee } 1621ac05c741SMark Maybee 1622fa9e4066Sahrens return (0); 1623fa9e4066Sahrens } 1624fa9e4066Sahrens 1625cdb0ab79Smaybee /* 1626cdb0ab79Smaybee * Free space in a file 1627cdb0ab79Smaybee * 1628cdb0ab79Smaybee * IN: zp - znode of file to free data in. 1629cdb0ab79Smaybee * off - start of range 1630cdb0ab79Smaybee * len - end of range (0 => EOF) 1631cdb0ab79Smaybee * flag - current file open mode flags. 1632cdb0ab79Smaybee * log - TRUE if this action should be logged 1633cdb0ab79Smaybee * 1634f7170741SWill Andrews * RETURN: 0 on success, error code on failure 1635cdb0ab79Smaybee */ 1636cdb0ab79Smaybee int 1637cdb0ab79Smaybee zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) 1638cdb0ab79Smaybee { 1639cdb0ab79Smaybee vnode_t *vp = ZTOV(zp); 1640cdb0ab79Smaybee dmu_tx_t *tx; 1641cdb0ab79Smaybee zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1642cdb0ab79Smaybee zilog_t *zilog = zfsvfs->z_log; 16430a586ceaSMark Shellenbaum uint64_t mode; 16440a586ceaSMark Shellenbaum uint64_t mtime[2], ctime[2]; 1645db9986c7SMark Shellenbaum sa_bulk_attr_t bulk[3]; 16460a586ceaSMark Shellenbaum int count = 0; 1647cdb0ab79Smaybee int error; 1648cdeb8ec5SSimon Klinkert rl_t *rl; 1649cdb0ab79Smaybee 16500a586ceaSMark Shellenbaum if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_MODE(zfsvfs), &mode, 16510a586ceaSMark Shellenbaum sizeof (mode))) != 0) 16520a586ceaSMark Shellenbaum return (error); 16530a586ceaSMark Shellenbaum 16540a586ceaSMark Shellenbaum if (off > zp->z_size) { 1655cdeb8ec5SSimon Klinkert rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); 1656cdb0ab79Smaybee error = zfs_extend(zp, off+len); 1657cdb0ab79Smaybee if (error == 0 && log) 1658cdb0ab79Smaybee goto log; 1659cdeb8ec5SSimon Klinkert 1660cdeb8ec5SSimon Klinkert zfs_range_unlock(rl); 1661cdb0ab79Smaybee return (error); 1662cdb0ab79Smaybee } 1663cdb0ab79Smaybee 1664cdb0ab79Smaybee /* 1665cdb0ab79Smaybee * Check for any locks in the region to be freed. 1666cdb0ab79Smaybee */ 16670a586ceaSMark Shellenbaum if (MANDLOCK(vp, (mode_t)mode)) { 16680a586ceaSMark Shellenbaum uint64_t length = (len ? len : zp->z_size - off); 1669cdb0ab79Smaybee if (error = chklock(vp, FWRITE, off, length, flag, NULL)) 1670cdb0ab79Smaybee return (error); 1671cdb0ab79Smaybee } 1672cdb0ab79Smaybee 1673cdeb8ec5SSimon Klinkert if (len == 0 || off + len > zp->z_size) { 1674cdeb8ec5SSimon Klinkert rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); 1675cdeb8ec5SSimon Klinkert } else { 1676cdeb8ec5SSimon Klinkert ssize_t lock_off; 1677cdeb8ec5SSimon Klinkert ssize_t lock_len; 1678cdeb8ec5SSimon Klinkert #ifdef _KERNEL 1679cdeb8ec5SSimon Klinkert if (rz_zev_active()) { 1680cdeb8ec5SSimon Klinkert /* start of this megabyte */ 1681cdeb8ec5SSimon Klinkert lock_off = P2ALIGN(off, ZEV_L1_SIZE); 1682cdeb8ec5SSimon Klinkert /* full megabytes */ 1683cdeb8ec5SSimon Klinkert lock_len = len + (off - lock_off); 1684cdeb8ec5SSimon Klinkert lock_len = P2ROUNDUP(lock_len, ZEV_L1_SIZE); 1685cdeb8ec5SSimon Klinkert } else { 1686cdeb8ec5SSimon Klinkert lock_off = off; 1687cdeb8ec5SSimon Klinkert lock_len = len; 1688cdeb8ec5SSimon Klinkert } 1689cdeb8ec5SSimon Klinkert #else 1690cdeb8ec5SSimon Klinkert lock_off = off; 1691cdeb8ec5SSimon Klinkert lock_len = len; 1692cdeb8ec5SSimon Klinkert #endif 1693cdeb8ec5SSimon Klinkert rl = zfs_range_lock(zp, lock_off, lock_len, RL_WRITER); 1694cdeb8ec5SSimon Klinkert } 1695cdeb8ec5SSimon Klinkert 1696cdb0ab79Smaybee if (len == 0) { 1697cdb0ab79Smaybee error = zfs_trunc(zp, off); 1698cdb0ab79Smaybee } else { 1699cdb0ab79Smaybee if ((error = zfs_free_range(zp, off, len)) == 0 && 17000a586ceaSMark Shellenbaum off + len > zp->z_size) 1701cdb0ab79Smaybee error = zfs_extend(zp, off+len); 1702cdb0ab79Smaybee } 1703cdeb8ec5SSimon Klinkert 1704cdeb8ec5SSimon Klinkert if (error || !log) { 1705cdeb8ec5SSimon Klinkert zfs_range_unlock(rl); 1706cdb0ab79Smaybee return (error); 1707cdeb8ec5SSimon Klinkert } 1708cdb0ab79Smaybee log: 1709cdb0ab79Smaybee tx = dmu_tx_create(zfsvfs->z_os); 17100a586ceaSMark Shellenbaum dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); 17110a586ceaSMark Shellenbaum zfs_sa_upgrade_txholds(tx, zp); 1712e722410cSMatthew Ahrens error = dmu_tx_assign(tx, TXG_WAIT); 1713cdb0ab79Smaybee if (error) { 1714cdb0ab79Smaybee dmu_tx_abort(tx); 1715cdeb8ec5SSimon Klinkert zfs_range_unlock(rl); 1716cdb0ab79Smaybee return (error); 1717cdb0ab79Smaybee } 1718cdb0ab79Smaybee 17190a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, mtime, 16); 17200a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, ctime, 16); 1721db9986c7SMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), 1722db9986c7SMark Shellenbaum NULL, &zp->z_pflags, 8); 17230a586ceaSMark Shellenbaum zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); 17240a586ceaSMark Shellenbaum error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); 17250a586ceaSMark Shellenbaum ASSERT(error == 0); 17260a586ceaSMark Shellenbaum 1727cdb0ab79Smaybee zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); 1728cdeb8ec5SSimon Klinkert zfs_range_unlock(rl); 1729cdb0ab79Smaybee 1730cdb0ab79Smaybee dmu_tx_commit(tx); 1731cdb0ab79Smaybee return (0); 1732cdb0ab79Smaybee } 1733cdb0ab79Smaybee 1734fa9e4066Sahrens void 1735de8267e0Stimh zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) 1736fa9e4066Sahrens { 17370a586ceaSMark Shellenbaum uint64_t moid, obj, sa_obj, version; 1738de8267e0Stimh uint64_t sense = ZFS_CASE_SENSITIVE; 1739de8267e0Stimh uint64_t norm = 0; 1740de8267e0Stimh nvpair_t *elem; 1741fa9e4066Sahrens int error; 174259e7834dSMark Shellenbaum int i; 1743fa9e4066Sahrens znode_t *rootzp = NULL; 1744c701fde6SGleb Smirnoff zfsvfs_t *zfsvfs; 1745fa9e4066Sahrens vnode_t *vp; 1746fa9e4066Sahrens vattr_t vattr; 17474ccbb6e7Sahrens znode_t *zp; 174889459e17SMark Shellenbaum zfs_acl_ids_t acl_ids; 1749fa9e4066Sahrens 1750fa9e4066Sahrens /* 1751fa9e4066Sahrens * First attempt to create master node. 1752fa9e4066Sahrens */ 1753ea8dc4b6Seschrock /* 1754ea8dc4b6Seschrock * In an empty objset, there are no blocks to read and thus 1755ea8dc4b6Seschrock * there can be no i/o errors (which we assert below). 1756ea8dc4b6Seschrock */ 1757fa9e4066Sahrens moid = MASTER_NODE_OBJ; 1758fa9e4066Sahrens error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE, 1759fa9e4066Sahrens DMU_OT_NONE, 0, tx); 1760fa9e4066Sahrens ASSERT(error == 0); 1761fa9e4066Sahrens 1762fa9e4066Sahrens /* 1763fa9e4066Sahrens * Set starting attributes. 1764fa9e4066Sahrens */ 17650a586ceaSMark Shellenbaum version = zfs_zpl_version_map(spa_version(dmu_objset_spa(os))); 1766de8267e0Stimh elem = NULL; 1767de8267e0Stimh while ((elem = nvlist_next_nvpair(zplprops, elem)) != NULL) { 1768de8267e0Stimh /* For the moment we expect all zpl props to be uint64_ts */ 1769de8267e0Stimh uint64_t val; 1770de8267e0Stimh char *name; 1771fa9e4066Sahrens 1772de8267e0Stimh ASSERT(nvpair_type(elem) == DATA_TYPE_UINT64); 1773b3d911cbStimh VERIFY(nvpair_value_uint64(elem, &val) == 0); 1774de8267e0Stimh name = nvpair_name(elem); 1775de8267e0Stimh if (strcmp(name, zfs_prop_to_name(ZFS_PROP_VERSION)) == 0) { 177614843421SMatthew Ahrens if (val < version) 1777de8267e0Stimh version = val; 1778de8267e0Stimh } else { 1779de8267e0Stimh error = zap_update(os, moid, name, 8, 1, &val, tx); 1780de8267e0Stimh } 1781fa9e4066Sahrens ASSERT(error == 0); 1782de8267e0Stimh if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0) 1783de8267e0Stimh norm = val; 1784de8267e0Stimh else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0) 1785de8267e0Stimh sense = val; 1786de8267e0Stimh } 1787de8267e0Stimh ASSERT(version != 0); 178814843421SMatthew Ahrens error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx); 1789fa9e4066Sahrens 1790fa9e4066Sahrens /* 17910a586ceaSMark Shellenbaum * Create zap object used for SA attribute registration 17920a586ceaSMark Shellenbaum */ 17930a586ceaSMark Shellenbaum 17940a586ceaSMark Shellenbaum if (version >= ZPL_VERSION_SA) { 17950a586ceaSMark Shellenbaum sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE, 17960a586ceaSMark Shellenbaum DMU_OT_NONE, 0, tx); 17970a586ceaSMark Shellenbaum error = zap_add(os, moid, ZFS_SA_ATTRS, 8, 1, &sa_obj, tx); 17980a586ceaSMark Shellenbaum ASSERT(error == 0); 17990a586ceaSMark Shellenbaum } else { 18000a586ceaSMark Shellenbaum sa_obj = 0; 18010a586ceaSMark Shellenbaum } 18020a586ceaSMark Shellenbaum /* 1803fa9e4066Sahrens * Create a delete queue. 1804fa9e4066Sahrens */ 180514843421SMatthew Ahrens obj = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx); 1806fa9e4066Sahrens 180714843421SMatthew Ahrens error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx); 1808fa9e4066Sahrens ASSERT(error == 0); 1809fa9e4066Sahrens 1810fa9e4066Sahrens /* 1811fa9e4066Sahrens * Create root znode. Create minimal znode/vnode/zfsvfs 1812fa9e4066Sahrens * to allow zfs_mknode to work. 1813fa9e4066Sahrens */ 1814fa9e4066Sahrens vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; 1815fa9e4066Sahrens vattr.va_type = VDIR; 1816fa9e4066Sahrens vattr.va_mode = S_IFDIR|0755; 1817ecd6cf80Smarks vattr.va_uid = crgetuid(cr); 1818ecd6cf80Smarks vattr.va_gid = crgetgid(cr); 1819fa9e4066Sahrens 1820fa9e4066Sahrens rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP); 1821744947dcSTom Erickson ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs)); 1822744947dcSTom Erickson rootzp->z_moved = 0; 1823893a6d32Sahrens rootzp->z_unlinked = 0; 1824fa9e4066Sahrens rootzp->z_atime_dirty = 0; 18250a586ceaSMark Shellenbaum rootzp->z_is_sa = USE_SA(version, os); 1826fa9e4066Sahrens 1827fa9e4066Sahrens vp = ZTOV(rootzp); 1828fa9e4066Sahrens vn_reinit(vp); 1829fa9e4066Sahrens vp->v_type = VDIR; 1830fa9e4066Sahrens 1831c701fde6SGleb Smirnoff zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); 1832c701fde6SGleb Smirnoff zfsvfs->z_os = os; 1833c701fde6SGleb Smirnoff zfsvfs->z_parent = zfsvfs; 1834c701fde6SGleb Smirnoff zfsvfs->z_version = version; 1835c701fde6SGleb Smirnoff zfsvfs->z_use_fuids = USE_FUIDS(version, os); 1836c701fde6SGleb Smirnoff zfsvfs->z_use_sa = USE_SA(version, os); 1837c701fde6SGleb Smirnoff zfsvfs->z_norm = norm; 18380a586ceaSMark Shellenbaum 18391d8ccc7bSMark Shellenbaum error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END, 1840c701fde6SGleb Smirnoff &zfsvfs->z_attr_table); 18411d8ccc7bSMark Shellenbaum 18421d8ccc7bSMark Shellenbaum ASSERT(error == 0); 18430a586ceaSMark Shellenbaum 1844de8267e0Stimh /* 1845de8267e0Stimh * Fold case on file systems that are always or sometimes case 1846de8267e0Stimh * insensitive. 1847de8267e0Stimh */ 1848de8267e0Stimh if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED) 1849c701fde6SGleb Smirnoff zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER; 1850fa9e4066Sahrens 1851c701fde6SGleb Smirnoff mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); 1852c701fde6SGleb Smirnoff list_create(&zfsvfs->z_all_znodes, sizeof (znode_t), 1853fa9e4066Sahrens offsetof(znode_t, z_link_node)); 1854fa9e4066Sahrens 185559e7834dSMark Shellenbaum for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) 1856c701fde6SGleb Smirnoff mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); 185759e7834dSMark Shellenbaum 1858c701fde6SGleb Smirnoff rootzp->z_zfsvfs = zfsvfs; 185989459e17SMark Shellenbaum VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, 186089459e17SMark Shellenbaum cr, NULL, &acl_ids)); 18610a586ceaSMark Shellenbaum zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids); 1862874395d5Smaybee ASSERT3P(zp, ==, rootzp); 1863b5fca8f8Stomee ASSERT(!vn_in_dnlc(ZTOV(rootzp))); /* not valid to move */ 18644ccbb6e7Sahrens error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); 1865fa9e4066Sahrens ASSERT(error == 0); 186689459e17SMark Shellenbaum zfs_acl_ids_free(&acl_ids); 1867b5fca8f8Stomee POINTER_INVALIDATE(&rootzp->z_zfsvfs); 1868fa9e4066Sahrens 1869fa9e4066Sahrens ZTOV(rootzp)->v_count = 0; 18700a586ceaSMark Shellenbaum sa_handle_destroy(rootzp->z_sa_hdl); 1871fa9e4066Sahrens kmem_cache_free(znode_cache, rootzp); 1872743a77edSAlan Wright 1873743a77edSAlan Wright /* 1874743a77edSAlan Wright * Create shares directory 1875743a77edSAlan Wright */ 1876743a77edSAlan Wright 1877c701fde6SGleb Smirnoff error = zfs_create_share_dir(zfsvfs, tx); 187889459e17SMark Shellenbaum 1879743a77edSAlan Wright ASSERT(error == 0); 188059e7834dSMark Shellenbaum 188159e7834dSMark Shellenbaum for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) 1882c701fde6SGleb Smirnoff mutex_destroy(&zfsvfs->z_hold_mtx[i]); 1883c701fde6SGleb Smirnoff kmem_free(zfsvfs, sizeof (zfsvfs_t)); 1884fa9e4066Sahrens } 188555434c77Sek110237 1886da6c28aaSamw #endif /* _KERNEL */ 18870a586ceaSMark Shellenbaum 188899d5e173STim Haley static int 188999d5e173STim Haley zfs_sa_setup(objset_t *osp, sa_attr_type_t **sa_table) 189099d5e173STim Haley { 189199d5e173STim Haley uint64_t sa_obj = 0; 189299d5e173STim Haley int error; 189399d5e173STim Haley 189499d5e173STim Haley error = zap_lookup(osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); 189599d5e173STim Haley if (error != 0 && error != ENOENT) 189699d5e173STim Haley return (error); 189799d5e173STim Haley 189899d5e173STim Haley error = sa_setup(osp, sa_obj, zfs_attr_table, ZPL_END, sa_table); 189999d5e173STim Haley return (error); 190099d5e173STim Haley } 190199d5e173STim Haley 190299d5e173STim Haley static int 190399d5e173STim Haley zfs_grab_sa_handle(objset_t *osp, uint64_t obj, sa_handle_t **hdlp, 1904163eb7ffSTim Haley dmu_buf_t **db, void *tag) 190599d5e173STim Haley { 190699d5e173STim Haley dmu_object_info_t doi; 190799d5e173STim Haley int error; 190899d5e173STim Haley 1909163eb7ffSTim Haley if ((error = sa_buf_hold(osp, obj, tag, db)) != 0) 191099d5e173STim Haley return (error); 191199d5e173STim Haley 191299d5e173STim Haley dmu_object_info_from_db(*db, &doi); 191399d5e173STim Haley if ((doi.doi_bonus_type != DMU_OT_SA && 191499d5e173STim Haley doi.doi_bonus_type != DMU_OT_ZNODE) || 191599d5e173STim Haley doi.doi_bonus_type == DMU_OT_ZNODE && 191699d5e173STim Haley doi.doi_bonus_size < sizeof (znode_phys_t)) { 1917163eb7ffSTim Haley sa_buf_rele(*db, tag); 1918be6fd75aSMatthew Ahrens return (SET_ERROR(ENOTSUP)); 191999d5e173STim Haley } 192099d5e173STim Haley 192199d5e173STim Haley error = sa_handle_get(osp, obj, NULL, SA_HDL_PRIVATE, hdlp); 192299d5e173STim Haley if (error != 0) { 1923163eb7ffSTim Haley sa_buf_rele(*db, tag); 192499d5e173STim Haley return (error); 192599d5e173STim Haley } 192699d5e173STim Haley 192799d5e173STim Haley return (0); 192899d5e173STim Haley } 192999d5e173STim Haley 193099d5e173STim Haley void 1931163eb7ffSTim Haley zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, void *tag) 193299d5e173STim Haley { 193399d5e173STim Haley sa_handle_destroy(hdl); 1934163eb7ffSTim Haley sa_buf_rele(db, tag); 193599d5e173STim Haley } 193699d5e173STim Haley 193755434c77Sek110237 /* 193855434c77Sek110237 * Given an object number, return its parent object number and whether 193955434c77Sek110237 * or not the object is an extended attribute directory. 194055434c77Sek110237 */ 194155434c77Sek110237 static int 19421ce39b5fSJeremy Jones zfs_obj_to_pobj(objset_t *osp, sa_handle_t *hdl, sa_attr_type_t *sa_table, 19431ce39b5fSJeremy Jones uint64_t *pobjp, int *is_xattrdir) 194455434c77Sek110237 { 19450a586ceaSMark Shellenbaum uint64_t parent; 19460a586ceaSMark Shellenbaum uint64_t pflags; 19470a586ceaSMark Shellenbaum uint64_t mode; 19481ce39b5fSJeremy Jones uint64_t parent_mode; 19490a586ceaSMark Shellenbaum sa_bulk_attr_t bulk[3]; 19501ce39b5fSJeremy Jones sa_handle_t *sa_hdl; 19511ce39b5fSJeremy Jones dmu_buf_t *sa_db; 19520a586ceaSMark Shellenbaum int count = 0; 195399d5e173STim Haley int error; 195455434c77Sek110237 195599d5e173STim Haley SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_PARENT], NULL, 195699d5e173STim Haley &parent, sizeof (parent)); 19570a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_FLAGS], NULL, 195899d5e173STim Haley &pflags, sizeof (pflags)); 19590a586ceaSMark Shellenbaum SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL, 196099d5e173STim Haley &mode, sizeof (mode)); 19610a586ceaSMark Shellenbaum 196299d5e173STim Haley if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0) 19630a586ceaSMark Shellenbaum return (error); 196499d5e173STim Haley 19651ce39b5fSJeremy Jones /* 19661ce39b5fSJeremy Jones * When a link is removed its parent pointer is not changed and will 19671ce39b5fSJeremy Jones * be invalid. There are two cases where a link is removed but the 19681ce39b5fSJeremy Jones * file stays around, when it goes to the delete queue and when there 19691ce39b5fSJeremy Jones * are additional links. 19701ce39b5fSJeremy Jones */ 19711ce39b5fSJeremy Jones error = zfs_grab_sa_handle(osp, parent, &sa_hdl, &sa_db, FTAG); 19721ce39b5fSJeremy Jones if (error != 0) 19731ce39b5fSJeremy Jones return (error); 19741ce39b5fSJeremy Jones 19751ce39b5fSJeremy Jones error = sa_lookup(sa_hdl, ZPL_MODE, &parent_mode, sizeof (parent_mode)); 19761ce39b5fSJeremy Jones zfs_release_sa_handle(sa_hdl, sa_db, FTAG); 19771ce39b5fSJeremy Jones if (error != 0) 19781ce39b5fSJeremy Jones return (error); 19791ce39b5fSJeremy Jones 19800a586ceaSMark Shellenbaum *is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode); 198155434c77Sek110237 19821ce39b5fSJeremy Jones /* 19831ce39b5fSJeremy Jones * Extended attributes can be applied to files, directories, etc. 19841ce39b5fSJeremy Jones * Otherwise the parent must be a directory. 19851ce39b5fSJeremy Jones */ 19861ce39b5fSJeremy Jones if (!*is_xattrdir && !S_ISDIR(parent_mode)) 1987be6fd75aSMatthew Ahrens return (SET_ERROR(EINVAL)); 19881ce39b5fSJeremy Jones 19891ce39b5fSJeremy Jones *pobjp = parent; 19901ce39b5fSJeremy Jones 199155434c77Sek110237 return (0); 199255434c77Sek110237 } 199355434c77Sek110237 199499d5e173STim Haley /* 199599d5e173STim Haley * Given an object number, return some zpl level statistics 199699d5e173STim Haley */ 199799d5e173STim Haley static int 199899d5e173STim Haley zfs_obj_to_stats_impl(sa_handle_t *hdl, sa_attr_type_t *sa_table, 199999d5e173STim Haley zfs_stat_t *sb) 200055434c77Sek110237 { 200199d5e173STim Haley sa_bulk_attr_t bulk[4]; 200299d5e173STim Haley int count = 0; 200399d5e173STim Haley 200499d5e173STim Haley SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL, 200599d5e173STim Haley &sb->zs_mode, sizeof (sb->zs_mode)); 200699d5e173STim Haley SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_GEN], NULL, 200799d5e173STim Haley &sb->zs_gen, sizeof (sb->zs_gen)); 200899d5e173STim Haley SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_LINKS], NULL, 200999d5e173STim Haley &sb->zs_links, sizeof (sb->zs_links)); 201099d5e173STim Haley SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_CTIME], NULL, 201199d5e173STim Haley &sb->zs_ctime, sizeof (sb->zs_ctime)); 201299d5e173STim Haley 201399d5e173STim Haley return (sa_bulk_lookup(hdl, bulk, count)); 201499d5e173STim Haley } 201599d5e173STim Haley 201699d5e173STim Haley static int 201799d5e173STim Haley zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, 201899d5e173STim Haley sa_attr_type_t *sa_table, char *buf, int len) 201999d5e173STim Haley { 202099d5e173STim Haley sa_handle_t *sa_hdl; 202199d5e173STim Haley sa_handle_t *prevhdl = NULL; 202299d5e173STim Haley dmu_buf_t *prevdb = NULL; 202399d5e173STim Haley dmu_buf_t *sa_db = NULL; 202455434c77Sek110237 char *path = buf + len - 1; 202555434c77Sek110237 int error; 202655434c77Sek110237 202755434c77Sek110237 *path = '\0'; 202899d5e173STim Haley sa_hdl = hdl; 20290a586ceaSMark Shellenbaum 203055434c77Sek110237 for (;;) { 203155434c77Sek110237 uint64_t pobj; 203255434c77Sek110237 char component[MAXNAMELEN + 2]; 203355434c77Sek110237 size_t complen; 203455434c77Sek110237 int is_xattrdir; 203555434c77Sek110237 203699d5e173STim Haley if (prevdb) 2037163eb7ffSTim Haley zfs_release_sa_handle(prevhdl, prevdb, FTAG); 203899d5e173STim Haley 20391ce39b5fSJeremy Jones if ((error = zfs_obj_to_pobj(osp, sa_hdl, sa_table, &pobj, 204099d5e173STim Haley &is_xattrdir)) != 0) 204155434c77Sek110237 break; 204255434c77Sek110237 204355434c77Sek110237 if (pobj == obj) { 204455434c77Sek110237 if (path[0] != '/') 204555434c77Sek110237 *--path = '/'; 204655434c77Sek110237 break; 204755434c77Sek110237 } 204855434c77Sek110237 204955434c77Sek110237 component[0] = '/'; 205055434c77Sek110237 if (is_xattrdir) { 205155434c77Sek110237 (void) sprintf(component + 1, "<xattrdir>"); 205255434c77Sek110237 } else { 2053e7437265Sahrens error = zap_value_search(osp, pobj, obj, 2054e7437265Sahrens ZFS_DIRENT_OBJ(-1ULL), component + 1); 205555434c77Sek110237 if (error != 0) 205655434c77Sek110237 break; 205755434c77Sek110237 } 205855434c77Sek110237 205955434c77Sek110237 complen = strlen(component); 206055434c77Sek110237 path -= complen; 206155434c77Sek110237 ASSERT(path >= buf); 206255434c77Sek110237 bcopy(component, path, complen); 206355434c77Sek110237 obj = pobj; 206499d5e173STim Haley 206599d5e173STim Haley if (sa_hdl != hdl) { 206699d5e173STim Haley prevhdl = sa_hdl; 206799d5e173STim Haley prevdb = sa_db; 206899d5e173STim Haley } 2069163eb7ffSTim Haley error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db, FTAG); 207099d5e173STim Haley if (error != 0) { 207199d5e173STim Haley sa_hdl = prevhdl; 207299d5e173STim Haley sa_db = prevdb; 207399d5e173STim Haley break; 207499d5e173STim Haley } 207599d5e173STim Haley } 207699d5e173STim Haley 207799d5e173STim Haley if (sa_hdl != NULL && sa_hdl != hdl) { 207899d5e173STim Haley ASSERT(sa_db != NULL); 2079163eb7ffSTim Haley zfs_release_sa_handle(sa_hdl, sa_db, FTAG); 208055434c77Sek110237 } 208155434c77Sek110237 208255434c77Sek110237 if (error == 0) 208355434c77Sek110237 (void) memmove(buf, path, buf + len - path); 20840a586ceaSMark Shellenbaum 208555434c77Sek110237 return (error); 208655434c77Sek110237 } 208799d5e173STim Haley 208899d5e173STim Haley int 208999d5e173STim Haley zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len) 209099d5e173STim Haley { 209199d5e173STim Haley sa_attr_type_t *sa_table; 209299d5e173STim Haley sa_handle_t *hdl; 209399d5e173STim Haley dmu_buf_t *db; 209499d5e173STim Haley int error; 209599d5e173STim Haley 209699d5e173STim Haley error = zfs_sa_setup(osp, &sa_table); 209799d5e173STim Haley if (error != 0) 209899d5e173STim Haley return (error); 209999d5e173STim Haley 2100163eb7ffSTim Haley error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); 210199d5e173STim Haley if (error != 0) 210299d5e173STim Haley return (error); 210399d5e173STim Haley 210499d5e173STim Haley error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); 210599d5e173STim Haley 2106163eb7ffSTim Haley zfs_release_sa_handle(hdl, db, FTAG); 210799d5e173STim Haley return (error); 210899d5e173STim Haley } 210999d5e173STim Haley 211099d5e173STim Haley int 211199d5e173STim Haley zfs_obj_to_stats(objset_t *osp, uint64_t obj, zfs_stat_t *sb, 211299d5e173STim Haley char *buf, int len) 211399d5e173STim Haley { 211499d5e173STim Haley char *path = buf + len - 1; 211599d5e173STim Haley sa_attr_type_t *sa_table; 211699d5e173STim Haley sa_handle_t *hdl; 211799d5e173STim Haley dmu_buf_t *db; 211899d5e173STim Haley int error; 211999d5e173STim Haley 212099d5e173STim Haley *path = '\0'; 212199d5e173STim Haley 212299d5e173STim Haley error = zfs_sa_setup(osp, &sa_table); 212399d5e173STim Haley if (error != 0) 212499d5e173STim Haley return (error); 212599d5e173STim Haley 2126163eb7ffSTim Haley error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); 212799d5e173STim Haley if (error != 0) 212899d5e173STim Haley return (error); 212999d5e173STim Haley 213099d5e173STim Haley error = zfs_obj_to_stats_impl(hdl, sa_table, sb); 213199d5e173STim Haley if (error != 0) { 2132163eb7ffSTim Haley zfs_release_sa_handle(hdl, db, FTAG); 213399d5e173STim Haley return (error); 213499d5e173STim Haley } 213599d5e173STim Haley 213699d5e173STim Haley error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); 213799d5e173STim Haley 2138163eb7ffSTim Haley zfs_release_sa_handle(hdl, db, FTAG); 213999d5e173STim Haley return (error); 214099d5e173STim Haley } 2141