0001
0002
0003
0004
0005
0006 #include <linux/hashtable.h>
0007 #include "props.h"
0008 #include "btrfs_inode.h"
0009 #include "transaction.h"
0010 #include "ctree.h"
0011 #include "xattr.h"
0012 #include "compression.h"
0013
0014 #define BTRFS_PROP_HANDLERS_HT_BITS 8
0015 static DEFINE_HASHTABLE(prop_handlers_ht, BTRFS_PROP_HANDLERS_HT_BITS);
0016
0017 struct prop_handler {
0018 struct hlist_node node;
0019 const char *xattr_name;
0020 int (*validate)(const struct btrfs_inode *inode, const char *value,
0021 size_t len);
0022 int (*apply)(struct inode *inode, const char *value, size_t len);
0023 const char *(*extract)(struct inode *inode);
0024 bool (*ignore)(const struct btrfs_inode *inode);
0025 int inheritable;
0026 };
0027
0028 static const struct hlist_head *find_prop_handlers_by_hash(const u64 hash)
0029 {
0030 struct hlist_head *h;
0031
0032 h = &prop_handlers_ht[hash_min(hash, BTRFS_PROP_HANDLERS_HT_BITS)];
0033 if (hlist_empty(h))
0034 return NULL;
0035
0036 return h;
0037 }
0038
0039 static const struct prop_handler *
0040 find_prop_handler(const char *name,
0041 const struct hlist_head *handlers)
0042 {
0043 struct prop_handler *h;
0044
0045 if (!handlers) {
0046 u64 hash = btrfs_name_hash(name, strlen(name));
0047
0048 handlers = find_prop_handlers_by_hash(hash);
0049 if (!handlers)
0050 return NULL;
0051 }
0052
0053 hlist_for_each_entry(h, handlers, node)
0054 if (!strcmp(h->xattr_name, name))
0055 return h;
0056
0057 return NULL;
0058 }
0059
0060 int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
0061 const char *value, size_t value_len)
0062 {
0063 const struct prop_handler *handler;
0064
0065 if (strlen(name) <= XATTR_BTRFS_PREFIX_LEN)
0066 return -EINVAL;
0067
0068 handler = find_prop_handler(name, NULL);
0069 if (!handler)
0070 return -EINVAL;
0071
0072 if (value_len == 0)
0073 return 0;
0074
0075 return handler->validate(inode, value, value_len);
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name)
0091 {
0092 const struct prop_handler *handler;
0093
0094 handler = find_prop_handler(name, NULL);
0095 ASSERT(handler != NULL);
0096
0097 return handler->ignore(inode);
0098 }
0099
0100 int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
0101 const char *name, const char *value, size_t value_len,
0102 int flags)
0103 {
0104 const struct prop_handler *handler;
0105 int ret;
0106
0107 handler = find_prop_handler(name, NULL);
0108 if (!handler)
0109 return -EINVAL;
0110
0111 if (value_len == 0) {
0112 ret = btrfs_setxattr(trans, inode, handler->xattr_name,
0113 NULL, 0, flags);
0114 if (ret)
0115 return ret;
0116
0117 ret = handler->apply(inode, NULL, 0);
0118 ASSERT(ret == 0);
0119
0120 return ret;
0121 }
0122
0123 ret = btrfs_setxattr(trans, inode, handler->xattr_name, value,
0124 value_len, flags);
0125 if (ret)
0126 return ret;
0127 ret = handler->apply(inode, value, value_len);
0128 if (ret) {
0129 btrfs_setxattr(trans, inode, handler->xattr_name, NULL,
0130 0, flags);
0131 return ret;
0132 }
0133
0134 set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
0135
0136 return 0;
0137 }
0138
0139 static int iterate_object_props(struct btrfs_root *root,
0140 struct btrfs_path *path,
0141 u64 objectid,
0142 void (*iterator)(void *,
0143 const struct prop_handler *,
0144 const char *,
0145 size_t),
0146 void *ctx)
0147 {
0148 int ret;
0149 char *name_buf = NULL;
0150 char *value_buf = NULL;
0151 int name_buf_len = 0;
0152 int value_buf_len = 0;
0153
0154 while (1) {
0155 struct btrfs_key key;
0156 struct btrfs_dir_item *di;
0157 struct extent_buffer *leaf;
0158 u32 total_len, cur, this_len;
0159 int slot;
0160 const struct hlist_head *handlers;
0161
0162 slot = path->slots[0];
0163 leaf = path->nodes[0];
0164
0165 if (slot >= btrfs_header_nritems(leaf)) {
0166 ret = btrfs_next_leaf(root, path);
0167 if (ret < 0)
0168 goto out;
0169 else if (ret > 0)
0170 break;
0171 continue;
0172 }
0173
0174 btrfs_item_key_to_cpu(leaf, &key, slot);
0175 if (key.objectid != objectid)
0176 break;
0177 if (key.type != BTRFS_XATTR_ITEM_KEY)
0178 break;
0179
0180 handlers = find_prop_handlers_by_hash(key.offset);
0181 if (!handlers)
0182 goto next_slot;
0183
0184 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
0185 cur = 0;
0186 total_len = btrfs_item_size(leaf, slot);
0187
0188 while (cur < total_len) {
0189 u32 name_len = btrfs_dir_name_len(leaf, di);
0190 u32 data_len = btrfs_dir_data_len(leaf, di);
0191 unsigned long name_ptr, data_ptr;
0192 const struct prop_handler *handler;
0193
0194 this_len = sizeof(*di) + name_len + data_len;
0195 name_ptr = (unsigned long)(di + 1);
0196 data_ptr = name_ptr + name_len;
0197
0198 if (name_len <= XATTR_BTRFS_PREFIX_LEN ||
0199 memcmp_extent_buffer(leaf, XATTR_BTRFS_PREFIX,
0200 name_ptr,
0201 XATTR_BTRFS_PREFIX_LEN))
0202 goto next_dir_item;
0203
0204 if (name_len >= name_buf_len) {
0205 kfree(name_buf);
0206 name_buf_len = name_len + 1;
0207 name_buf = kmalloc(name_buf_len, GFP_NOFS);
0208 if (!name_buf) {
0209 ret = -ENOMEM;
0210 goto out;
0211 }
0212 }
0213 read_extent_buffer(leaf, name_buf, name_ptr, name_len);
0214 name_buf[name_len] = '\0';
0215
0216 handler = find_prop_handler(name_buf, handlers);
0217 if (!handler)
0218 goto next_dir_item;
0219
0220 if (data_len > value_buf_len) {
0221 kfree(value_buf);
0222 value_buf_len = data_len;
0223 value_buf = kmalloc(data_len, GFP_NOFS);
0224 if (!value_buf) {
0225 ret = -ENOMEM;
0226 goto out;
0227 }
0228 }
0229 read_extent_buffer(leaf, value_buf, data_ptr, data_len);
0230
0231 iterator(ctx, handler, value_buf, data_len);
0232 next_dir_item:
0233 cur += this_len;
0234 di = (struct btrfs_dir_item *)((char *) di + this_len);
0235 }
0236
0237 next_slot:
0238 path->slots[0]++;
0239 }
0240
0241 ret = 0;
0242 out:
0243 btrfs_release_path(path);
0244 kfree(name_buf);
0245 kfree(value_buf);
0246
0247 return ret;
0248 }
0249
0250 static void inode_prop_iterator(void *ctx,
0251 const struct prop_handler *handler,
0252 const char *value,
0253 size_t len)
0254 {
0255 struct inode *inode = ctx;
0256 struct btrfs_root *root = BTRFS_I(inode)->root;
0257 int ret;
0258
0259 ret = handler->apply(inode, value, len);
0260 if (unlikely(ret))
0261 btrfs_warn(root->fs_info,
0262 "error applying prop %s to ino %llu (root %llu): %d",
0263 handler->xattr_name, btrfs_ino(BTRFS_I(inode)),
0264 root->root_key.objectid, ret);
0265 else
0266 set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
0267 }
0268
0269 int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path)
0270 {
0271 struct btrfs_root *root = BTRFS_I(inode)->root;
0272 u64 ino = btrfs_ino(BTRFS_I(inode));
0273 int ret;
0274
0275 ret = iterate_object_props(root, path, ino, inode_prop_iterator, inode);
0276
0277 return ret;
0278 }
0279
0280 static int prop_compression_validate(const struct btrfs_inode *inode,
0281 const char *value, size_t len)
0282 {
0283 if (!btrfs_inode_can_compress(inode))
0284 return -EINVAL;
0285
0286 if (!value)
0287 return 0;
0288
0289 if (btrfs_compress_is_valid_type(value, len))
0290 return 0;
0291
0292 if ((len == 2 && strncmp("no", value, 2) == 0) ||
0293 (len == 4 && strncmp("none", value, 4) == 0))
0294 return 0;
0295
0296 return -EINVAL;
0297 }
0298
0299 static int prop_compression_apply(struct inode *inode, const char *value,
0300 size_t len)
0301 {
0302 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
0303 int type;
0304
0305
0306 if (len == 0) {
0307 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
0308 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
0309 BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE;
0310 return 0;
0311 }
0312
0313
0314 if ((len == 2 && strncmp("no", value, 2) == 0) ||
0315 (len == 4 && strncmp("none", value, 4) == 0)) {
0316 BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
0317 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
0318 BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE;
0319
0320 return 0;
0321 }
0322
0323 if (!strncmp("lzo", value, 3)) {
0324 type = BTRFS_COMPRESS_LZO;
0325 btrfs_set_fs_incompat(fs_info, COMPRESS_LZO);
0326 } else if (!strncmp("zlib", value, 4)) {
0327 type = BTRFS_COMPRESS_ZLIB;
0328 } else if (!strncmp("zstd", value, 4)) {
0329 type = BTRFS_COMPRESS_ZSTD;
0330 btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
0331 } else {
0332 return -EINVAL;
0333 }
0334
0335 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
0336 BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;
0337 BTRFS_I(inode)->prop_compress = type;
0338
0339 return 0;
0340 }
0341
0342 static bool prop_compression_ignore(const struct btrfs_inode *inode)
0343 {
0344
0345
0346
0347
0348
0349
0350
0351 if (!S_ISREG(inode->vfs_inode.i_mode) &&
0352 !S_ISDIR(inode->vfs_inode.i_mode))
0353 return true;
0354
0355 return false;
0356 }
0357
0358 static const char *prop_compression_extract(struct inode *inode)
0359 {
0360 switch (BTRFS_I(inode)->prop_compress) {
0361 case BTRFS_COMPRESS_ZLIB:
0362 case BTRFS_COMPRESS_LZO:
0363 case BTRFS_COMPRESS_ZSTD:
0364 return btrfs_compress_type2str(BTRFS_I(inode)->prop_compress);
0365 default:
0366 break;
0367 }
0368
0369 return NULL;
0370 }
0371
0372 static struct prop_handler prop_handlers[] = {
0373 {
0374 .xattr_name = XATTR_BTRFS_PREFIX "compression",
0375 .validate = prop_compression_validate,
0376 .apply = prop_compression_apply,
0377 .extract = prop_compression_extract,
0378 .ignore = prop_compression_ignore,
0379 .inheritable = 1
0380 },
0381 };
0382
0383 int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans,
0384 struct inode *inode, struct inode *parent)
0385 {
0386 struct btrfs_root *root = BTRFS_I(inode)->root;
0387 struct btrfs_fs_info *fs_info = root->fs_info;
0388 int ret;
0389 int i;
0390 bool need_reserve = false;
0391
0392 if (!test_bit(BTRFS_INODE_HAS_PROPS,
0393 &BTRFS_I(parent)->runtime_flags))
0394 return 0;
0395
0396 for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
0397 const struct prop_handler *h = &prop_handlers[i];
0398 const char *value;
0399 u64 num_bytes = 0;
0400
0401 if (!h->inheritable)
0402 continue;
0403
0404 if (h->ignore(BTRFS_I(inode)))
0405 continue;
0406
0407 value = h->extract(parent);
0408 if (!value)
0409 continue;
0410
0411
0412
0413
0414
0415 ret = h->validate(BTRFS_I(inode), value, strlen(value));
0416 if (ret)
0417 continue;
0418
0419
0420
0421
0422
0423
0424
0425
0426 if (need_reserve) {
0427 num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1);
0428 ret = btrfs_block_rsv_add(fs_info, trans->block_rsv,
0429 num_bytes,
0430 BTRFS_RESERVE_NO_FLUSH);
0431 if (ret)
0432 return ret;
0433 }
0434
0435 ret = btrfs_setxattr(trans, inode, h->xattr_name, value,
0436 strlen(value), 0);
0437 if (!ret) {
0438 ret = h->apply(inode, value, strlen(value));
0439 if (ret)
0440 btrfs_setxattr(trans, inode, h->xattr_name,
0441 NULL, 0, 0);
0442 else
0443 set_bit(BTRFS_INODE_HAS_PROPS,
0444 &BTRFS_I(inode)->runtime_flags);
0445 }
0446
0447 if (need_reserve) {
0448 btrfs_block_rsv_release(fs_info, trans->block_rsv,
0449 num_bytes, NULL);
0450 if (ret)
0451 return ret;
0452 }
0453 need_reserve = true;
0454 }
0455
0456 return 0;
0457 }
0458
0459 void __init btrfs_props_init(void)
0460 {
0461 int i;
0462
0463 for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
0464 struct prop_handler *p = &prop_handlers[i];
0465 u64 h = btrfs_name_hash(p->xattr_name, strlen(p->xattr_name));
0466
0467 hash_add(prop_handlers_ht, &p->node, h);
0468 }
0469 }
0470