hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/btrfs/props.c
....@@ -23,36 +23,6 @@
2323 int inheritable;
2424 };
2525
26
-static int prop_compression_validate(const char *value, size_t len);
27
-static int prop_compression_apply(struct inode *inode,
28
- const char *value,
29
- size_t len);
30
-static const char *prop_compression_extract(struct inode *inode);
31
-
32
-static struct prop_handler prop_handlers[] = {
33
- {
34
- .xattr_name = XATTR_BTRFS_PREFIX "compression",
35
- .validate = prop_compression_validate,
36
- .apply = prop_compression_apply,
37
- .extract = prop_compression_extract,
38
- .inheritable = 1
39
- },
40
-};
41
-
42
-void __init btrfs_props_init(void)
43
-{
44
- int i;
45
-
46
- hash_init(prop_handlers_ht);
47
-
48
- for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
49
- struct prop_handler *p = &prop_handlers[i];
50
- u64 h = btrfs_name_hash(p->xattr_name, strlen(p->xattr_name));
51
-
52
- hash_add(prop_handlers_ht, &p->node, h);
53
- }
54
-}
55
-
5626 static const struct hlist_head *find_prop_handlers_by_hash(const u64 hash)
5727 {
5828 struct hlist_head *h;
....@@ -85,15 +55,9 @@
8555 return NULL;
8656 }
8757
88
-static int __btrfs_set_prop(struct btrfs_trans_handle *trans,
89
- struct inode *inode,
90
- const char *name,
91
- const char *value,
92
- size_t value_len,
93
- int flags)
58
+int btrfs_validate_prop(const char *name, const char *value, size_t value_len)
9459 {
9560 const struct prop_handler *handler;
96
- int ret;
9761
9862 if (strlen(name) <= XATTR_BTRFS_PREFIX_LEN)
9963 return -EINVAL;
....@@ -102,9 +66,26 @@
10266 if (!handler)
10367 return -EINVAL;
10468
69
+ if (value_len == 0)
70
+ return 0;
71
+
72
+ return handler->validate(value, value_len);
73
+}
74
+
75
+int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
76
+ const char *name, const char *value, size_t value_len,
77
+ int flags)
78
+{
79
+ const struct prop_handler *handler;
80
+ int ret;
81
+
82
+ handler = find_prop_handler(name, NULL);
83
+ if (!handler)
84
+ return -EINVAL;
85
+
10586 if (value_len == 0) {
10687 ret = btrfs_setxattr(trans, inode, handler->xattr_name,
107
- NULL, 0, flags);
88
+ NULL, 0, flags);
10889 if (ret)
10990 return ret;
11091
....@@ -114,32 +95,20 @@
11495 return ret;
11596 }
11697
117
- ret = handler->validate(value, value_len);
118
- if (ret)
119
- return ret;
120
- ret = btrfs_setxattr(trans, inode, handler->xattr_name,
121
- value, value_len, flags);
98
+ ret = btrfs_setxattr(trans, inode, handler->xattr_name, value,
99
+ value_len, flags);
122100 if (ret)
123101 return ret;
124102 ret = handler->apply(inode, value, value_len);
125103 if (ret) {
126
- btrfs_setxattr(trans, inode, handler->xattr_name,
127
- NULL, 0, flags);
104
+ btrfs_setxattr(trans, inode, handler->xattr_name, NULL,
105
+ 0, flags);
128106 return ret;
129107 }
130108
131109 set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
132110
133111 return 0;
134
-}
135
-
136
-int btrfs_set_prop(struct inode *inode,
137
- const char *name,
138
- const char *value,
139
- size_t value_len,
140
- int flags)
141
-{
142
- return __btrfs_set_prop(NULL, inode, name, value, value_len, flags);
143112 }
144113
145114 static int iterate_object_props(struct btrfs_root *root,
....@@ -283,97 +252,18 @@
283252 return ret;
284253 }
285254
286
-static int inherit_props(struct btrfs_trans_handle *trans,
287
- struct inode *inode,
288
- struct inode *parent)
289
-{
290
- struct btrfs_root *root = BTRFS_I(inode)->root;
291
- struct btrfs_fs_info *fs_info = root->fs_info;
292
- int ret;
293
- int i;
294
-
295
- if (!test_bit(BTRFS_INODE_HAS_PROPS,
296
- &BTRFS_I(parent)->runtime_flags))
297
- return 0;
298
-
299
- for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
300
- const struct prop_handler *h = &prop_handlers[i];
301
- const char *value;
302
- u64 num_bytes;
303
-
304
- if (!h->inheritable)
305
- continue;
306
-
307
- value = h->extract(parent);
308
- if (!value)
309
- continue;
310
-
311
- num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
312
- ret = btrfs_block_rsv_add(root, trans->block_rsv,
313
- num_bytes, BTRFS_RESERVE_NO_FLUSH);
314
- if (ret)
315
- goto out;
316
- ret = __btrfs_set_prop(trans, inode, h->xattr_name,
317
- value, strlen(value), 0);
318
- btrfs_block_rsv_release(fs_info, trans->block_rsv, num_bytes);
319
- if (ret)
320
- goto out;
321
- }
322
- ret = 0;
323
-out:
324
- return ret;
325
-}
326
-
327
-int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans,
328
- struct inode *inode,
329
- struct inode *dir)
330
-{
331
- if (!dir)
332
- return 0;
333
-
334
- return inherit_props(trans, inode, dir);
335
-}
336
-
337
-int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans,
338
- struct btrfs_root *root,
339
- struct btrfs_root *parent_root)
340
-{
341
- struct super_block *sb = root->fs_info->sb;
342
- struct btrfs_key key;
343
- struct inode *parent_inode, *child_inode;
344
- int ret;
345
-
346
- key.objectid = BTRFS_FIRST_FREE_OBJECTID;
347
- key.type = BTRFS_INODE_ITEM_KEY;
348
- key.offset = 0;
349
-
350
- parent_inode = btrfs_iget(sb, &key, parent_root, NULL);
351
- if (IS_ERR(parent_inode))
352
- return PTR_ERR(parent_inode);
353
-
354
- child_inode = btrfs_iget(sb, &key, root, NULL);
355
- if (IS_ERR(child_inode)) {
356
- iput(parent_inode);
357
- return PTR_ERR(child_inode);
358
- }
359
-
360
- ret = inherit_props(trans, child_inode, parent_inode);
361
- iput(child_inode);
362
- iput(parent_inode);
363
-
364
- return ret;
365
-}
366
-
367255 static int prop_compression_validate(const char *value, size_t len)
368256 {
257
+ if (!value)
258
+ return 0;
259
+
369260 if (btrfs_compress_is_valid_type(value, len))
370261 return 0;
371262
372263 return -EINVAL;
373264 }
374265
375
-static int prop_compression_apply(struct inode *inode,
376
- const char *value,
266
+static int prop_compression_apply(struct inode *inode, const char *value,
377267 size_t len)
378268 {
379269 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
....@@ -420,4 +310,133 @@
420310 return NULL;
421311 }
422312
313
+static struct prop_handler prop_handlers[] = {
314
+ {
315
+ .xattr_name = XATTR_BTRFS_PREFIX "compression",
316
+ .validate = prop_compression_validate,
317
+ .apply = prop_compression_apply,
318
+ .extract = prop_compression_extract,
319
+ .inheritable = 1
320
+ },
321
+};
322
+
323
+static int inherit_props(struct btrfs_trans_handle *trans,
324
+ struct inode *inode,
325
+ struct inode *parent)
326
+{
327
+ struct btrfs_root *root = BTRFS_I(inode)->root;
328
+ struct btrfs_fs_info *fs_info = root->fs_info;
329
+ int ret;
330
+ int i;
331
+ bool need_reserve = false;
332
+
333
+ if (!test_bit(BTRFS_INODE_HAS_PROPS,
334
+ &BTRFS_I(parent)->runtime_flags))
335
+ return 0;
336
+
337
+ for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
338
+ const struct prop_handler *h = &prop_handlers[i];
339
+ const char *value;
340
+ u64 num_bytes = 0;
341
+
342
+ if (!h->inheritable)
343
+ continue;
344
+
345
+ value = h->extract(parent);
346
+ if (!value)
347
+ continue;
348
+
349
+ /*
350
+ * This is not strictly necessary as the property should be
351
+ * valid, but in case it isn't, don't propagate it futher.
352
+ */
353
+ ret = h->validate(value, strlen(value));
354
+ if (ret)
355
+ continue;
356
+
357
+ /*
358
+ * Currently callers should be reserving 1 item for properties,
359
+ * since we only have 1 property that we currently support. If
360
+ * we add more in the future we need to try and reserve more
361
+ * space for them. But we should also revisit how we do space
362
+ * reservations if we do add more properties in the future.
363
+ */
364
+ if (need_reserve) {
365
+ num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1);
366
+ ret = btrfs_block_rsv_add(root, trans->block_rsv,
367
+ num_bytes, BTRFS_RESERVE_NO_FLUSH);
368
+ if (ret)
369
+ return ret;
370
+ }
371
+
372
+ ret = btrfs_setxattr(trans, inode, h->xattr_name, value,
373
+ strlen(value), 0);
374
+ if (!ret) {
375
+ ret = h->apply(inode, value, strlen(value));
376
+ if (ret)
377
+ btrfs_setxattr(trans, inode, h->xattr_name,
378
+ NULL, 0, 0);
379
+ else
380
+ set_bit(BTRFS_INODE_HAS_PROPS,
381
+ &BTRFS_I(inode)->runtime_flags);
382
+ }
383
+
384
+ if (need_reserve) {
385
+ btrfs_block_rsv_release(fs_info, trans->block_rsv,
386
+ num_bytes, NULL);
387
+ if (ret)
388
+ return ret;
389
+ }
390
+ need_reserve = true;
391
+ }
392
+
393
+ return 0;
394
+}
395
+
396
+int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans,
397
+ struct inode *inode,
398
+ struct inode *dir)
399
+{
400
+ if (!dir)
401
+ return 0;
402
+
403
+ return inherit_props(trans, inode, dir);
404
+}
405
+
406
+int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans,
407
+ struct btrfs_root *root,
408
+ struct btrfs_root *parent_root)
409
+{
410
+ struct super_block *sb = root->fs_info->sb;
411
+ struct inode *parent_inode, *child_inode;
412
+ int ret;
413
+
414
+ parent_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, parent_root);
415
+ if (IS_ERR(parent_inode))
416
+ return PTR_ERR(parent_inode);
417
+
418
+ child_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, root);
419
+ if (IS_ERR(child_inode)) {
420
+ iput(parent_inode);
421
+ return PTR_ERR(child_inode);
422
+ }
423
+
424
+ ret = inherit_props(trans, child_inode, parent_inode);
425
+ iput(child_inode);
426
+ iput(parent_inode);
427
+
428
+ return ret;
429
+}
430
+
431
+void __init btrfs_props_init(void)
432
+{
433
+ int i;
434
+
435
+ for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
436
+ struct prop_handler *p = &prop_handlers[i];
437
+ u64 h = btrfs_name_hash(p->xattr_name, strlen(p->xattr_name));
438
+
439
+ hash_add(prop_handlers_ht, &p->node, h);
440
+ }
441
+}
423442