1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2014 Filipe David Borba Manana <fdmanana@gmail.com> 4 */ 5 6 #include <linux/hashtable.h> 7 #include "messages.h" 8 #include "props.h" 9 #include "btrfs_inode.h" 10 #include "transaction.h" 11 #include "ctree.h" 12 #include "xattr.h" 13 #include "compression.h" 14 #include "space-info.h" 15 #include "fs.h" 16 #include "accessors.h" 17 #include "super.h" 18 #include "dir-item.h" 19 20 #define BTRFS_PROP_HANDLERS_HT_BITS 8 21 static DEFINE_HASHTABLE(prop_handlers_ht, BTRFS_PROP_HANDLERS_HT_BITS); 22 23 struct prop_handler { 24 struct hlist_node node; 25 const char *xattr_name; 26 int (*validate)(const struct btrfs_inode *inode, const char *value, 27 size_t len); 28 int (*apply)(struct inode *inode, const char *value, size_t len); 29 const char *(*extract)(struct inode *inode); 30 bool (*ignore)(const struct btrfs_inode *inode); 31 int inheritable; 32 }; 33 34 static const struct hlist_head *find_prop_handlers_by_hash(const u64 hash) 35 { 36 struct hlist_head *h; 37 38 h = &prop_handlers_ht[hash_min(hash, BTRFS_PROP_HANDLERS_HT_BITS)]; 39 if (hlist_empty(h)) 40 return NULL; 41 42 return h; 43 } 44 45 static const struct prop_handler * 46 find_prop_handler(const char *name, 47 const struct hlist_head *handlers) 48 { 49 struct prop_handler *h; 50 51 if (!handlers) { 52 u64 hash = btrfs_name_hash(name, strlen(name)); 53 54 handlers = find_prop_handlers_by_hash(hash); 55 if (!handlers) 56 return NULL; 57 } 58 59 hlist_for_each_entry(h, handlers, node) 60 if (!strcmp(h->xattr_name, name)) 61 return h; 62 63 return NULL; 64 } 65 66 int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name, 67 const char *value, size_t value_len) 68 { 69 const struct prop_handler *handler; 70 71 if (strlen(name) <= XATTR_BTRFS_PREFIX_LEN) 72 return -EINVAL; 73 74 handler = find_prop_handler(name, NULL); 75 if (!handler) 76 return -EINVAL; 77 78 if (value_len == 0) 79 return 0; 80 81 return handler->validate(inode, value, value_len); 82 } 83 84 /* 85 * Check if a property should be ignored (not set) for an inode. 86 * 87 * @inode: The target inode. 88 * @name: The property's name. 89 * 90 * The caller must be sure the given property name is valid, for example by 91 * having previously called btrfs_validate_prop(). 92 * 93 * Returns: true if the property should be ignored for the given inode 94 * false if the property must not be ignored for the given inode 95 */ 96 bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name) 97 { 98 const struct prop_handler *handler; 99 100 handler = find_prop_handler(name, NULL); 101 ASSERT(handler != NULL); 102 103 return handler->ignore(inode); 104 } 105 106 int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode, 107 const char *name, const char *value, size_t value_len, 108 int flags) 109 { 110 const struct prop_handler *handler; 111 int ret; 112 113 handler = find_prop_handler(name, NULL); 114 if (!handler) 115 return -EINVAL; 116 117 if (value_len == 0) { 118 ret = btrfs_setxattr(trans, inode, handler->xattr_name, 119 NULL, 0, flags); 120 if (ret) 121 return ret; 122 123 ret = handler->apply(inode, NULL, 0); 124 ASSERT(ret == 0); 125 126 return ret; 127 } 128 129 ret = btrfs_setxattr(trans, inode, handler->xattr_name, value, 130 value_len, flags); 131 if (ret) 132 return ret; 133 ret = handler->apply(inode, value, value_len); 134 if (ret) { 135 btrfs_setxattr(trans, inode, handler->xattr_name, NULL, 136 0, flags); 137 return ret; 138 } 139 140 set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags); 141 142 return 0; 143 } 144 145 static int iterate_object_props(struct btrfs_root *root, 146 struct btrfs_path *path, 147 u64 objectid, 148 void (*iterator)(void *, 149 const struct prop_handler *, 150 const char *, 151 size_t), 152 void *ctx) 153 { 154 int ret; 155 char *name_buf = NULL; 156 char *value_buf = NULL; 157 int name_buf_len = 0; 158 int value_buf_len = 0; 159 160 while (1) { 161 struct btrfs_key key; 162 struct btrfs_dir_item *di; 163 struct extent_buffer *leaf; 164 u32 total_len, cur, this_len; 165 int slot; 166 const struct hlist_head *handlers; 167 168 slot = path->slots[0]; 169 leaf = path->nodes[0]; 170 171 if (slot >= btrfs_header_nritems(leaf)) { 172 ret = btrfs_next_leaf(root, path); 173 if (ret < 0) 174 goto out; 175 else if (ret > 0) 176 break; 177 continue; 178 } 179 180 btrfs_item_key_to_cpu(leaf, &key, slot); 181 if (key.objectid != objectid) 182 break; 183 if (key.type != BTRFS_XATTR_ITEM_KEY) 184 break; 185 186 handlers = find_prop_handlers_by_hash(key.offset); 187 if (!handlers) 188 goto next_slot; 189 190 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 191 cur = 0; 192 total_len = btrfs_item_size(leaf, slot); 193 194 while (cur < total_len) { 195 u32 name_len = btrfs_dir_name_len(leaf, di); 196 u32 data_len = btrfs_dir_data_len(leaf, di); 197 unsigned long name_ptr, data_ptr; 198 const struct prop_handler *handler; 199 200 this_len = sizeof(*di) + name_len + data_len; 201 name_ptr = (unsigned long)(di + 1); 202 data_ptr = name_ptr + name_len; 203 204 if (name_len <= XATTR_BTRFS_PREFIX_LEN || 205 memcmp_extent_buffer(leaf, XATTR_BTRFS_PREFIX, 206 name_ptr, 207 XATTR_BTRFS_PREFIX_LEN)) 208 goto next_dir_item; 209 210 if (name_len >= name_buf_len) { 211 kfree(name_buf); 212 name_buf_len = name_len + 1; 213 name_buf = kmalloc(name_buf_len, GFP_NOFS); 214 if (!name_buf) { 215 ret = -ENOMEM; 216 goto out; 217 } 218 } 219 read_extent_buffer(leaf, name_buf, name_ptr, name_len); 220 name_buf[name_len] = '\0'; 221 222 handler = find_prop_handler(name_buf, handlers); 223 if (!handler) 224 goto next_dir_item; 225 226 if (data_len > value_buf_len) { 227 kfree(value_buf); 228 value_buf_len = data_len; 229 value_buf = kmalloc(data_len, GFP_NOFS); 230 if (!value_buf) { 231 ret = -ENOMEM; 232 goto out; 233 } 234 } 235 read_extent_buffer(leaf, value_buf, data_ptr, data_len); 236 237 iterator(ctx, handler, value_buf, data_len); 238 next_dir_item: 239 cur += this_len; 240 di = (struct btrfs_dir_item *)((char *) di + this_len); 241 } 242 243 next_slot: 244 path->slots[0]++; 245 } 246 247 ret = 0; 248 out: 249 btrfs_release_path(path); 250 kfree(name_buf); 251 kfree(value_buf); 252 253 return ret; 254 } 255 256 static void inode_prop_iterator(void *ctx, 257 const struct prop_handler *handler, 258 const char *value, 259 size_t len) 260 { 261 struct inode *inode = ctx; 262 struct btrfs_root *root = BTRFS_I(inode)->root; 263 int ret; 264 265 ret = handler->apply(inode, value, len); 266 if (unlikely(ret)) 267 btrfs_warn(root->fs_info, 268 "error applying prop %s to ino %llu (root %llu): %d", 269 handler->xattr_name, btrfs_ino(BTRFS_I(inode)), 270 root->root_key.objectid, ret); 271 else 272 set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags); 273 } 274 275 int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path) 276 { 277 struct btrfs_root *root = BTRFS_I(inode)->root; 278 u64 ino = btrfs_ino(BTRFS_I(inode)); 279 280 return iterate_object_props(root, path, ino, inode_prop_iterator, inode); 281 } 282 283 static int prop_compression_validate(const struct btrfs_inode *inode, 284 const char *value, size_t len) 285 { 286 if (!btrfs_inode_can_compress(inode)) 287 return -EINVAL; 288 289 if (!value) 290 return 0; 291 292 if (btrfs_compress_is_valid_type(value, len)) 293 return 0; 294 295 if ((len == 2 && strncmp("no", value, 2) == 0) || 296 (len == 4 && strncmp("none", value, 4) == 0)) 297 return 0; 298 299 return -EINVAL; 300 } 301 302 static int prop_compression_apply(struct inode *inode, const char *value, 303 size_t len) 304 { 305 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 306 int type; 307 308 /* Reset to defaults */ 309 if (len == 0) { 310 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS; 311 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; 312 BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE; 313 return 0; 314 } 315 316 /* Set NOCOMPRESS flag */ 317 if ((len == 2 && strncmp("no", value, 2) == 0) || 318 (len == 4 && strncmp("none", value, 4) == 0)) { 319 BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; 320 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS; 321 BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE; 322 323 return 0; 324 } 325 326 if (!strncmp("lzo", value, 3)) { 327 type = BTRFS_COMPRESS_LZO; 328 btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); 329 } else if (!strncmp("zlib", value, 4)) { 330 type = BTRFS_COMPRESS_ZLIB; 331 } else if (!strncmp("zstd", value, 4)) { 332 type = BTRFS_COMPRESS_ZSTD; 333 btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); 334 } else { 335 return -EINVAL; 336 } 337 338 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; 339 BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; 340 BTRFS_I(inode)->prop_compress = type; 341 342 return 0; 343 } 344 345 static bool prop_compression_ignore(const struct btrfs_inode *inode) 346 { 347 /* 348 * Compression only has effect for regular files, and for directories 349 * we set it just to propagate it to new files created inside them. 350 * Everything else (symlinks, devices, sockets, fifos) is pointless as 351 * it will do nothing, so don't waste metadata space on a compression 352 * xattr for anything that is neither a file nor a directory. 353 */ 354 if (!S_ISREG(inode->vfs_inode.i_mode) && 355 !S_ISDIR(inode->vfs_inode.i_mode)) 356 return true; 357 358 return false; 359 } 360 361 static const char *prop_compression_extract(struct inode *inode) 362 { 363 switch (BTRFS_I(inode)->prop_compress) { 364 case BTRFS_COMPRESS_ZLIB: 365 case BTRFS_COMPRESS_LZO: 366 case BTRFS_COMPRESS_ZSTD: 367 return btrfs_compress_type2str(BTRFS_I(inode)->prop_compress); 368 default: 369 break; 370 } 371 372 return NULL; 373 } 374 375 static struct prop_handler prop_handlers[] = { 376 { 377 .xattr_name = XATTR_BTRFS_PREFIX "compression", 378 .validate = prop_compression_validate, 379 .apply = prop_compression_apply, 380 .extract = prop_compression_extract, 381 .ignore = prop_compression_ignore, 382 .inheritable = 1 383 }, 384 }; 385 386 int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans, 387 struct inode *inode, struct inode *parent) 388 { 389 struct btrfs_root *root = BTRFS_I(inode)->root; 390 struct btrfs_fs_info *fs_info = root->fs_info; 391 int ret; 392 int i; 393 bool need_reserve = false; 394 395 if (!test_bit(BTRFS_INODE_HAS_PROPS, 396 &BTRFS_I(parent)->runtime_flags)) 397 return 0; 398 399 for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) { 400 const struct prop_handler *h = &prop_handlers[i]; 401 const char *value; 402 u64 num_bytes = 0; 403 404 if (!h->inheritable) 405 continue; 406 407 if (h->ignore(BTRFS_I(inode))) 408 continue; 409 410 value = h->extract(parent); 411 if (!value) 412 continue; 413 414 /* 415 * This is not strictly necessary as the property should be 416 * valid, but in case it isn't, don't propagate it further. 417 */ 418 ret = h->validate(BTRFS_I(inode), value, strlen(value)); 419 if (ret) 420 continue; 421 422 /* 423 * Currently callers should be reserving 1 item for properties, 424 * since we only have 1 property that we currently support. If 425 * we add more in the future we need to try and reserve more 426 * space for them. But we should also revisit how we do space 427 * reservations if we do add more properties in the future. 428 */ 429 if (need_reserve) { 430 num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1); 431 ret = btrfs_block_rsv_add(fs_info, trans->block_rsv, 432 num_bytes, 433 BTRFS_RESERVE_NO_FLUSH); 434 if (ret) 435 return ret; 436 } 437 438 ret = btrfs_setxattr(trans, inode, h->xattr_name, value, 439 strlen(value), 0); 440 if (!ret) { 441 ret = h->apply(inode, value, strlen(value)); 442 if (ret) 443 btrfs_setxattr(trans, inode, h->xattr_name, 444 NULL, 0, 0); 445 else 446 set_bit(BTRFS_INODE_HAS_PROPS, 447 &BTRFS_I(inode)->runtime_flags); 448 } 449 450 if (need_reserve) { 451 btrfs_block_rsv_release(fs_info, trans->block_rsv, 452 num_bytes, NULL); 453 if (ret) 454 return ret; 455 } 456 need_reserve = true; 457 } 458 459 return 0; 460 } 461 462 int __init btrfs_props_init(void) 463 { 464 int i; 465 466 for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) { 467 struct prop_handler *p = &prop_handlers[i]; 468 u64 h = btrfs_name_hash(p->xattr_name, strlen(p->xattr_name)); 469 470 hash_add(prop_handlers_ht, &p->node, h); 471 } 472 return 0; 473 } 474 475