1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <sys/zfs_context.h> 27 #include <sys/vnode.h> 28 #include <sys/sa.h> 29 #include <sys/zfs_acl.h> 30 #include <sys/zfs_sa.h> 31 #include <sys/dmu_objset.h> 32 #include <sys/sa_impl.h> 33 #include <sys/zfeature.h> 34 35 /* 36 * ZPL attribute registration table. 37 * Order of attributes doesn't matter 38 * a unique value will be assigned for each 39 * attribute that is file system specific 40 * 41 * This is just the set of ZPL attributes that this 42 * version of ZFS deals with natively. The file system 43 * could have other attributes stored in files, but they will be 44 * ignored. The SA framework will preserve them, just that 45 * this version of ZFS won't change or delete them. 46 */ 47 48 const sa_attr_reg_t zfs_attr_table[ZPL_END+1] = { 49 {"ZPL_ATIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 0}, 50 {"ZPL_MTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 1}, 51 {"ZPL_CTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 2}, 52 {"ZPL_CRTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 3}, 53 {"ZPL_GEN", sizeof (uint64_t), SA_UINT64_ARRAY, 4}, 54 {"ZPL_MODE", sizeof (uint64_t), SA_UINT64_ARRAY, 5}, 55 {"ZPL_SIZE", sizeof (uint64_t), SA_UINT64_ARRAY, 6}, 56 {"ZPL_PARENT", sizeof (uint64_t), SA_UINT64_ARRAY, 7}, 57 {"ZPL_LINKS", sizeof (uint64_t), SA_UINT64_ARRAY, 8}, 58 {"ZPL_XATTR", sizeof (uint64_t), SA_UINT64_ARRAY, 9}, 59 {"ZPL_RDEV", sizeof (uint64_t), SA_UINT64_ARRAY, 10}, 60 {"ZPL_FLAGS", sizeof (uint64_t), SA_UINT64_ARRAY, 11}, 61 {"ZPL_UID", sizeof (uint64_t), SA_UINT64_ARRAY, 12}, 62 {"ZPL_GID", sizeof (uint64_t), SA_UINT64_ARRAY, 13}, 63 {"ZPL_PAD", sizeof (uint64_t) * 4, SA_UINT64_ARRAY, 14}, 64 {"ZPL_ZNODE_ACL", 88, SA_UINT8_ARRAY, 15}, 65 {"ZPL_DACL_COUNT", sizeof (uint64_t), SA_UINT64_ARRAY, 0}, 66 {"ZPL_SYMLINK", 0, SA_UINT8_ARRAY, 0}, 67 {"ZPL_SCANSTAMP", 32, SA_UINT8_ARRAY, 0}, 68 {"ZPL_DACL_ACES", 0, SA_ACL, 0}, 69 {"ZPL_DXATTR", 0, SA_UINT8_ARRAY, 0}, 70 {"ZPL_PROJID", sizeof (uint64_t), SA_UINT64_ARRAY, 0}, 71 {NULL, 0, 0, 0} 72 }; 73 74 75 #ifdef _KERNEL 76 static int zfs_zil_saxattr = 1; 77 78 int 79 zfs_sa_readlink(znode_t *zp, zfs_uio_t *uio) 80 { 81 dmu_buf_t *db = sa_get_db(zp->z_sa_hdl); 82 size_t bufsz; 83 int error; 84 85 bufsz = zp->z_size; 86 if (bufsz + ZFS_OLD_ZNODE_PHYS_SIZE <= db->db_size) { 87 error = zfs_uiomove((caddr_t)db->db_data + 88 ZFS_OLD_ZNODE_PHYS_SIZE, 89 MIN((size_t)bufsz, zfs_uio_resid(uio)), UIO_READ, uio); 90 } else { 91 dmu_buf_t *dbp; 92 if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id, 93 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) { 94 error = zfs_uiomove(dbp->db_data, 95 MIN((size_t)bufsz, zfs_uio_resid(uio)), UIO_READ, 96 uio); 97 dmu_buf_rele(dbp, FTAG); 98 } 99 } 100 return (error); 101 } 102 103 void 104 zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx) 105 { 106 dmu_buf_t *db = sa_get_db(zp->z_sa_hdl); 107 108 if (ZFS_OLD_ZNODE_PHYS_SIZE + len <= dmu_bonus_max()) { 109 VERIFY0(dmu_set_bonus(db, len + ZFS_OLD_ZNODE_PHYS_SIZE, tx)); 110 if (len) { 111 memcpy((caddr_t)db->db_data + 112 ZFS_OLD_ZNODE_PHYS_SIZE, link, len); 113 } 114 } else { 115 dmu_buf_t *dbp; 116 117 zfs_grow_blocksize(zp, len, tx); 118 VERIFY0(dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id, 0, FTAG, &dbp, 119 DMU_READ_NO_PREFETCH)); 120 121 dmu_buf_will_dirty(dbp, tx); 122 123 ASSERT3U(len, <=, dbp->db_size); 124 memcpy(dbp->db_data, link, len); 125 dmu_buf_rele(dbp, FTAG); 126 } 127 } 128 129 void 130 zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap) 131 { 132 zfsvfs_t *zfsvfs = ZTOZSB(zp); 133 xoptattr_t *xoap; 134 135 ASSERT(MUTEX_HELD(&zp->z_lock)); 136 VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); 137 if (zp->z_is_sa) { 138 if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), 139 &xoap->xoa_av_scanstamp, 140 sizeof (xoap->xoa_av_scanstamp)) != 0) 141 return; 142 } else { 143 dmu_object_info_t doi; 144 dmu_buf_t *db = sa_get_db(zp->z_sa_hdl); 145 int len; 146 147 if (!(zp->z_pflags & ZFS_BONUS_SCANSTAMP)) 148 return; 149 150 sa_object_info(zp->z_sa_hdl, &doi); 151 len = sizeof (xoap->xoa_av_scanstamp) + 152 ZFS_OLD_ZNODE_PHYS_SIZE; 153 154 if (len <= doi.doi_bonus_size) { 155 (void) memcpy(xoap->xoa_av_scanstamp, 156 (caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, 157 sizeof (xoap->xoa_av_scanstamp)); 158 } 159 } 160 XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP); 161 } 162 163 void 164 zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) 165 { 166 zfsvfs_t *zfsvfs = ZTOZSB(zp); 167 xoptattr_t *xoap; 168 169 ASSERT(MUTEX_HELD(&zp->z_lock)); 170 VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); 171 if (zp->z_is_sa) 172 VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), 173 &xoap->xoa_av_scanstamp, 174 sizeof (xoap->xoa_av_scanstamp), tx)); 175 else { 176 dmu_object_info_t doi; 177 dmu_buf_t *db = sa_get_db(zp->z_sa_hdl); 178 int len; 179 180 sa_object_info(zp->z_sa_hdl, &doi); 181 len = sizeof (xoap->xoa_av_scanstamp) + 182 ZFS_OLD_ZNODE_PHYS_SIZE; 183 if (len > doi.doi_bonus_size) 184 VERIFY(dmu_set_bonus(db, len, tx) == 0); 185 (void) memcpy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, 186 xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp)); 187 188 zp->z_pflags |= ZFS_BONUS_SCANSTAMP; 189 VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs), 190 &zp->z_pflags, sizeof (uint64_t), tx)); 191 } 192 } 193 194 int 195 zfs_sa_get_xattr(znode_t *zp) 196 { 197 zfsvfs_t *zfsvfs = ZTOZSB(zp); 198 char *obj; 199 int size; 200 int error; 201 202 ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock)); 203 ASSERT(!zp->z_xattr_cached); 204 ASSERT(zp->z_is_sa); 205 206 error = sa_size(zp->z_sa_hdl, SA_ZPL_DXATTR(zfsvfs), &size); 207 if (error) { 208 if (error == ENOENT) 209 return nvlist_alloc(&zp->z_xattr_cached, 210 NV_UNIQUE_NAME, KM_SLEEP); 211 else 212 return (error); 213 } 214 215 obj = vmem_alloc(size, KM_SLEEP); 216 217 error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DXATTR(zfsvfs), obj, size); 218 if (error == 0) 219 error = nvlist_unpack(obj, size, &zp->z_xattr_cached, KM_SLEEP); 220 221 vmem_free(obj, size); 222 223 return (error); 224 } 225 226 int 227 zfs_sa_set_xattr(znode_t *zp, const char *name, const void *value, size_t vsize) 228 { 229 zfsvfs_t *zfsvfs = ZTOZSB(zp); 230 zilog_t *zilog; 231 dmu_tx_t *tx; 232 char *obj; 233 size_t size; 234 int error, logsaxattr = 0; 235 236 ASSERT(RW_WRITE_HELD(&zp->z_xattr_lock)); 237 ASSERT(zp->z_xattr_cached); 238 ASSERT(zp->z_is_sa); 239 240 error = nvlist_size(zp->z_xattr_cached, &size, NV_ENCODE_XDR); 241 if ((error == 0) && (size > SA_ATTR_MAX_LEN)) 242 error = SET_ERROR(EFBIG); 243 if (error) 244 goto out; 245 246 obj = vmem_alloc(size, KM_SLEEP); 247 248 error = nvlist_pack(zp->z_xattr_cached, &obj, &size, 249 NV_ENCODE_XDR, KM_SLEEP); 250 if (error) 251 goto out_free; 252 253 zilog = zfsvfs->z_log; 254 255 /* 256 * Users enable ZIL logging of xattr=sa operations by enabling the 257 * SPA_FEATURE_ZILSAXATTR feature on the pool. Feature is activated 258 * during zil_process_commit_list/zil_create, if enabled. 259 */ 260 if (spa_feature_is_enabled(zfsvfs->z_os->os_spa, 261 SPA_FEATURE_ZILSAXATTR) && zfs_zil_saxattr) 262 logsaxattr = 1; 263 264 tx = dmu_tx_create(zfsvfs->z_os); 265 dmu_tx_hold_sa_create(tx, size); 266 dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); 267 268 error = dmu_tx_assign(tx, DMU_TX_WAIT); 269 if (error) { 270 dmu_tx_abort(tx); 271 } else { 272 int count = 0; 273 sa_bulk_attr_t bulk[2]; 274 uint64_t ctime[2]; 275 276 if (logsaxattr) 277 zfs_log_setsaxattr(zilog, tx, TX_SETSAXATTR, zp, name, 278 value, vsize); 279 280 zfs_tstamp_update_setup(zp, STATE_CHANGED, NULL, ctime); 281 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DXATTR(zfsvfs), 282 NULL, obj, size); 283 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), 284 NULL, &ctime, 16); 285 VERIFY0(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx)); 286 287 dmu_tx_commit(tx); 288 if (logsaxattr && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) 289 zil_commit(zilog, 0); 290 } 291 out_free: 292 vmem_free(obj, size); 293 out: 294 return (error); 295 } 296 297 /* 298 * I'm not convinced we should do any of this upgrade. 299 * since the SA code can read both old/new znode formats 300 * with probably little to no performance difference. 301 * 302 * All new files will be created with the new format. 303 */ 304 305 void 306 zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx) 307 { 308 dmu_buf_t *db = sa_get_db(hdl); 309 znode_t *zp = sa_get_userdata(hdl); 310 zfsvfs_t *zfsvfs = ZTOZSB(zp); 311 int count = 0; 312 sa_bulk_attr_t *bulk, *sa_attrs; 313 zfs_acl_locator_cb_t locate = { 0 }; 314 uint64_t uid, gid, mode, rdev, xattr, parent, tmp_gen; 315 uint64_t crtime[2], mtime[2], ctime[2], atime[2]; 316 uint64_t links; 317 zfs_acl_phys_t znode_acl; 318 char scanstamp[AV_SCANSTAMP_SZ]; 319 boolean_t drop_lock = B_FALSE; 320 321 /* 322 * No upgrade if ACL isn't cached 323 * since we won't know which locks are held 324 * and ready the ACL would require special "locked" 325 * interfaces that would be messy 326 */ 327 if (zp->z_acl_cached == NULL || Z_ISLNK(ZTOTYPE(zp))) 328 return; 329 330 /* 331 * If the z_lock is held and we aren't the owner 332 * the just return since we don't want to deadlock 333 * trying to update the status of z_is_sa. This 334 * file can then be upgraded at a later time. 335 * 336 * Otherwise, we know we are doing the 337 * sa_update() that caused us to enter this function. 338 */ 339 if (MUTEX_NOT_HELD(&zp->z_lock)) { 340 if (mutex_tryenter(&zp->z_lock) == 0) 341 return; 342 else 343 drop_lock = B_TRUE; 344 } 345 346 /* First do a bulk query of the attributes that aren't cached */ 347 bulk = kmem_alloc(sizeof (sa_bulk_attr_t) * ZPL_END, KM_SLEEP); 348 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, &atime, 16); 349 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); 350 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); 351 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16); 352 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); 353 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8); 354 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8); 355 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zfsvfs), NULL, &rdev, 8); 356 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); 357 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); 358 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, &tmp_gen, 8); 359 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, 360 &znode_acl, 88); 361 362 if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) 363 goto done; 364 365 if (dmu_objset_projectquota_enabled(hdl->sa_os) && 366 !(zp->z_pflags & ZFS_PROJID)) { 367 zp->z_pflags |= ZFS_PROJID; 368 zp->z_projid = ZFS_DEFAULT_PROJID; 369 } 370 371 /* 372 * While the order here doesn't matter its best to try and organize 373 * it is such a way to pick up an already existing layout number 374 */ 375 count = 0; 376 sa_attrs = kmem_zalloc(sizeof (sa_bulk_attr_t) * ZPL_END, KM_SLEEP); 377 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); 378 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zfsvfs), NULL, 379 &zp->z_size, 8); 380 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zfsvfs), 381 NULL, &tmp_gen, 8); 382 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); 383 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); 384 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zfsvfs), 385 NULL, &parent, 8); 386 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zfsvfs), NULL, 387 &zp->z_pflags, 8); 388 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zfsvfs), NULL, 389 &atime, 16); 390 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zfsvfs), NULL, 391 &mtime, 16); 392 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zfsvfs), NULL, 393 &ctime, 16); 394 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zfsvfs), NULL, 395 &crtime, 16); 396 links = ZTONLNK(zp); 397 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zfsvfs), NULL, 398 &links, 8); 399 if (dmu_objset_projectquota_enabled(hdl->sa_os)) 400 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PROJID(zfsvfs), NULL, 401 &zp->z_projid, 8); 402 if (Z_ISBLK(ZTOTYPE(zp)) || Z_ISCHR(ZTOTYPE(zp))) 403 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zfsvfs), NULL, 404 &rdev, 8); 405 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zfsvfs), NULL, 406 &zp->z_acl_cached->z_acl_count, 8); 407 408 if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID) 409 zfs_acl_xform(zp, zp->z_acl_cached, CRED()); 410 411 locate.cb_aclp = zp->z_acl_cached; 412 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zfsvfs), 413 zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes); 414 415 if (xattr) 416 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zfsvfs), 417 NULL, &xattr, 8); 418 419 /* if scanstamp then add scanstamp */ 420 421 if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) { 422 memcpy(scanstamp, 423 (caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, 424 AV_SCANSTAMP_SZ); 425 SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zfsvfs), 426 NULL, scanstamp, AV_SCANSTAMP_SZ); 427 zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP; 428 } 429 430 VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0); 431 VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs, 432 count, tx) == 0); 433 if (znode_acl.z_acl_extern_obj) 434 VERIFY(0 == dmu_object_free(zfsvfs->z_os, 435 znode_acl.z_acl_extern_obj, tx)); 436 437 zp->z_is_sa = B_TRUE; 438 kmem_free(sa_attrs, sizeof (sa_bulk_attr_t) * ZPL_END); 439 done: 440 kmem_free(bulk, sizeof (sa_bulk_attr_t) * ZPL_END); 441 if (drop_lock) 442 mutex_exit(&zp->z_lock); 443 } 444 445 void 446 zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp) 447 { 448 if (!ZTOZSB(zp)->z_use_sa || zp->z_is_sa) 449 return; 450 451 452 dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); 453 454 if (zfs_external_acl(zp)) { 455 dmu_tx_hold_free(tx, zfs_external_acl(zp), 0, 456 DMU_OBJECT_END); 457 } 458 } 459 460 ZFS_MODULE_PARAM(zfs, zfs_, zil_saxattr, INT, ZMOD_RW, 461 "Disable xattr=sa extended attribute logging in ZIL by settng 0."); 462 463 EXPORT_SYMBOL(zfs_attr_table); 464 EXPORT_SYMBOL(zfs_sa_readlink); 465 EXPORT_SYMBOL(zfs_sa_symlink); 466 EXPORT_SYMBOL(zfs_sa_get_scanstamp); 467 EXPORT_SYMBOL(zfs_sa_set_scanstamp); 468 EXPORT_SYMBOL(zfs_sa_get_xattr); 469 EXPORT_SYMBOL(zfs_sa_set_xattr); 470 EXPORT_SYMBOL(zfs_sa_upgrade); 471 EXPORT_SYMBOL(zfs_sa_upgrade_txholds); 472 473 #endif 474