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