]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/xattr.c
Update bcachefs sources to f7ccf51390 bcachefs: durability
[bcachefs-tools-debian] / libbcachefs / xattr.c
1
2 #include "bcachefs.h"
3 #include "bkey_methods.h"
4 #include "btree_update.h"
5 #include "compress.h"
6 #include "extents.h"
7 #include "fs.h"
8 #include "str_hash.h"
9 #include "tier.h"
10 #include "xattr.h"
11
12 #include <linux/dcache.h>
13 #include <linux/posix_acl_xattr.h>
14 #include <linux/xattr.h>
15
16 static unsigned xattr_val_u64s(unsigned name_len, unsigned val_len)
17 {
18         return DIV_ROUND_UP(sizeof(struct bch_xattr) +
19                             name_len + val_len, sizeof(u64));
20 }
21
22 #define xattr_val(_xattr)       ((_xattr)->x_name + (_xattr)->x_name_len)
23
24 static const struct xattr_handler *bch2_xattr_type_to_handler(unsigned);
25
26 struct xattr_search_key {
27         u8              type;
28         struct qstr     name;
29 };
30
31 #define X_SEARCH(_type, _name, _len) ((struct xattr_search_key) \
32         { .type = _type, .name = QSTR_INIT(_name, _len) })
33
34 static u64 bch2_xattr_hash(const struct bch_hash_info *info,
35                           const struct xattr_search_key *key)
36 {
37         struct bch_str_hash_ctx ctx;
38
39         bch2_str_hash_init(&ctx, info);
40         bch2_str_hash_update(&ctx, info, &key->type, sizeof(key->type));
41         bch2_str_hash_update(&ctx, info, key->name.name, key->name.len);
42
43         return bch2_str_hash_end(&ctx, info);
44 }
45
46 static u64 xattr_hash_key(const struct bch_hash_info *info, const void *key)
47 {
48         return bch2_xattr_hash(info, key);
49 }
50
51 static u64 xattr_hash_bkey(const struct bch_hash_info *info, struct bkey_s_c k)
52 {
53         struct bkey_s_c_xattr x = bkey_s_c_to_xattr(k);
54
55         return bch2_xattr_hash(info,
56                  &X_SEARCH(x.v->x_type, x.v->x_name, x.v->x_name_len));
57 }
58
59 static bool xattr_cmp_key(struct bkey_s_c _l, const void *_r)
60 {
61         struct bkey_s_c_xattr l = bkey_s_c_to_xattr(_l);
62         const struct xattr_search_key *r = _r;
63
64         return l.v->x_type != r->type ||
65                 l.v->x_name_len != r->name.len ||
66                 memcmp(l.v->x_name, r->name.name, r->name.len);
67 }
68
69 static bool xattr_cmp_bkey(struct bkey_s_c _l, struct bkey_s_c _r)
70 {
71         struct bkey_s_c_xattr l = bkey_s_c_to_xattr(_l);
72         struct bkey_s_c_xattr r = bkey_s_c_to_xattr(_r);
73
74         return l.v->x_type != r.v->x_type ||
75                 l.v->x_name_len != r.v->x_name_len ||
76                 memcmp(l.v->x_name, r.v->x_name, r.v->x_name_len);
77 }
78
79 const struct bch_hash_desc bch2_xattr_hash_desc = {
80         .btree_id       = BTREE_ID_XATTRS,
81         .key_type       = BCH_XATTR,
82         .whiteout_type  = BCH_XATTR_WHITEOUT,
83         .hash_key       = xattr_hash_key,
84         .hash_bkey      = xattr_hash_bkey,
85         .cmp_key        = xattr_cmp_key,
86         .cmp_bkey       = xattr_cmp_bkey,
87 };
88
89 static const char *bch2_xattr_invalid(const struct bch_fs *c,
90                                      struct bkey_s_c k)
91 {
92         const struct xattr_handler *handler;
93         struct bkey_s_c_xattr xattr;
94         unsigned u64s;
95
96         switch (k.k->type) {
97         case BCH_XATTR:
98                 if (bkey_val_bytes(k.k) < sizeof(struct bch_xattr))
99                         return "value too small";
100
101                 xattr = bkey_s_c_to_xattr(k);
102                 u64s = xattr_val_u64s(xattr.v->x_name_len,
103                                       le16_to_cpu(xattr.v->x_val_len));
104
105                 if (bkey_val_u64s(k.k) < u64s)
106                         return "value too small";
107
108                 if (bkey_val_u64s(k.k) > u64s)
109                         return "value too big";
110
111                 handler = bch2_xattr_type_to_handler(xattr.v->x_type);
112                 if (!handler)
113                         return "invalid type";
114
115                 if (memchr(xattr.v->x_name, '\0', xattr.v->x_name_len))
116                         return "xattr name has invalid characters";
117
118                 return NULL;
119         case BCH_XATTR_WHITEOUT:
120                 return bkey_val_bytes(k.k) != 0
121                         ? "value size should be zero"
122                         : NULL;
123
124         default:
125                 return "invalid type";
126         }
127 }
128
129 static void bch2_xattr_to_text(struct bch_fs *c, char *buf,
130                               size_t size, struct bkey_s_c k)
131 {
132         const struct xattr_handler *handler;
133         struct bkey_s_c_xattr xattr;
134         size_t n = 0;
135
136         switch (k.k->type) {
137         case BCH_XATTR:
138                 xattr = bkey_s_c_to_xattr(k);
139
140                 handler = bch2_xattr_type_to_handler(xattr.v->x_type);
141                 if (handler && handler->prefix)
142                         n += scnprintf(buf + n, size - n, "%s", handler->prefix);
143                 else if (handler)
144                         n += scnprintf(buf + n, size - n, "(type %u)",
145                                        xattr.v->x_type);
146                 else
147                         n += scnprintf(buf + n, size - n, "(unknown type %u)",
148                                        xattr.v->x_type);
149
150                 n += bch_scnmemcpy(buf + n, size - n, xattr.v->x_name,
151                                    xattr.v->x_name_len);
152                 n += scnprintf(buf + n, size - n, ":");
153                 n += bch_scnmemcpy(buf + n, size - n, xattr_val(xattr.v),
154                                    le16_to_cpu(xattr.v->x_val_len));
155                 break;
156         case BCH_XATTR_WHITEOUT:
157                 scnprintf(buf, size, "whiteout");
158                 break;
159         }
160 }
161
162 const struct bkey_ops bch2_bkey_xattr_ops = {
163         .key_invalid    = bch2_xattr_invalid,
164         .val_to_text    = bch2_xattr_to_text,
165 };
166
167 int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode,
168                   const char *name, void *buffer, size_t size, int type)
169 {
170         struct btree_iter iter;
171         struct bkey_s_c k;
172         struct bkey_s_c_xattr xattr;
173         int ret;
174
175         k = bch2_hash_lookup(bch2_xattr_hash_desc, &inode->ei_str_hash, c,
176                              inode->v.i_ino, &iter,
177                              &X_SEARCH(type, name, strlen(name)));
178         if (IS_ERR(k.k))
179                 return bch2_btree_iter_unlock(&iter) ?: -ENODATA;
180
181         xattr = bkey_s_c_to_xattr(k);
182         ret = le16_to_cpu(xattr.v->x_val_len);
183         if (buffer) {
184                 if (ret > size)
185                         ret = -ERANGE;
186                 else
187                         memcpy(buffer, xattr_val(xattr.v), ret);
188         }
189
190         bch2_btree_iter_unlock(&iter);
191         return ret;
192 }
193
194 int __bch2_xattr_set(struct bch_fs *c, u64 inum,
195                     const struct bch_hash_info *hash_info,
196                     const char *name, const void *value, size_t size,
197                     int flags, int type, u64 *journal_seq)
198 {
199         struct xattr_search_key search = X_SEARCH(type, name, strlen(name));
200         int ret;
201
202         if (!value) {
203                 ret = bch2_hash_delete(bch2_xattr_hash_desc, hash_info,
204                                       c, inum,
205                                       journal_seq, &search);
206         } else {
207                 struct bkey_i_xattr *xattr;
208                 unsigned u64s = BKEY_U64s +
209                         xattr_val_u64s(search.name.len, size);
210
211                 if (u64s > U8_MAX)
212                         return -ERANGE;
213
214                 xattr = kmalloc(u64s * sizeof(u64), GFP_NOFS);
215                 if (!xattr)
216                         return -ENOMEM;
217
218                 bkey_xattr_init(&xattr->k_i);
219                 xattr->k.u64s           = u64s;
220                 xattr->v.x_type         = type;
221                 xattr->v.x_name_len     = search.name.len;
222                 xattr->v.x_val_len      = cpu_to_le16(size);
223                 memcpy(xattr->v.x_name, search.name.name, search.name.len);
224                 memcpy(xattr_val(&xattr->v), value, size);
225
226                 ret = bch2_hash_set(bch2_xattr_hash_desc, hash_info, c,
227                                 inum, journal_seq,
228                                 &xattr->k_i,
229                                 (flags & XATTR_CREATE ? BCH_HASH_SET_MUST_CREATE : 0)|
230                                 (flags & XATTR_REPLACE ? BCH_HASH_SET_MUST_REPLACE : 0));
231                 kfree(xattr);
232         }
233
234         if (ret == -ENOENT)
235                 ret = flags & XATTR_REPLACE ? -ENODATA : 0;
236
237         return ret;
238 }
239
240 int bch2_xattr_set(struct bch_fs *c, struct bch_inode_info *inode,
241                    const char *name, const void *value, size_t size,
242                    int flags, int type)
243 {
244         return __bch2_xattr_set(c, inode->v.i_ino, &inode->ei_str_hash,
245                                 name, value, size, flags, type,
246                                 &inode->ei_journal_seq);
247 }
248
249 static size_t bch2_xattr_emit(struct dentry *dentry,
250                              const struct bch_xattr *xattr,
251                              char *buffer, size_t buffer_size)
252 {
253         const struct xattr_handler *handler =
254                 bch2_xattr_type_to_handler(xattr->x_type);
255
256         if (handler && (!handler->list || handler->list(dentry))) {
257                 const char *prefix = handler->prefix ?: handler->name;
258                 const size_t prefix_len = strlen(prefix);
259                 const size_t total_len = prefix_len + xattr->x_name_len + 1;
260
261                 if (buffer && total_len <= buffer_size) {
262                         memcpy(buffer, prefix, prefix_len);
263                         memcpy(buffer + prefix_len,
264                                xattr->x_name, xattr->x_name_len);
265                         buffer[prefix_len + xattr->x_name_len] = '\0';
266                 }
267
268                 return total_len;
269         } else {
270                 return 0;
271         }
272 }
273
274 ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
275 {
276         struct bch_fs *c = dentry->d_sb->s_fs_info;
277         struct btree_iter iter;
278         struct bkey_s_c k;
279         const struct bch_xattr *xattr;
280         u64 inum = dentry->d_inode->i_ino;
281         ssize_t ret = 0;
282         size_t len;
283
284         for_each_btree_key(&iter, c, BTREE_ID_XATTRS, POS(inum, 0), 0, k) {
285                 BUG_ON(k.k->p.inode < inum);
286
287                 if (k.k->p.inode > inum)
288                         break;
289
290                 if (k.k->type != BCH_XATTR)
291                         continue;
292
293                 xattr = bkey_s_c_to_xattr(k).v;
294
295                 len = bch2_xattr_emit(dentry, xattr, buffer, buffer_size);
296                 if (buffer) {
297                         if (len > buffer_size) {
298                                 bch2_btree_iter_unlock(&iter);
299                                 return -ERANGE;
300                         }
301
302                         buffer += len;
303                         buffer_size -= len;
304                 }
305
306                 ret += len;
307
308         }
309         bch2_btree_iter_unlock(&iter);
310
311         return ret;
312 }
313
314 static int bch2_xattr_get_handler(const struct xattr_handler *handler,
315                                   struct dentry *dentry, struct inode *vinode,
316                                   const char *name, void *buffer, size_t size)
317 {
318         struct bch_inode_info *inode = to_bch_ei(vinode);
319         struct bch_fs *c = inode->v.i_sb->s_fs_info;
320
321         return bch2_xattr_get(c, inode, name, buffer, size, handler->flags);
322 }
323
324 static int bch2_xattr_set_handler(const struct xattr_handler *handler,
325                                   struct dentry *dentry, struct inode *vinode,
326                                   const char *name, const void *value,
327                                   size_t size, int flags)
328 {
329         struct bch_inode_info *inode = to_bch_ei(vinode);
330         struct bch_fs *c = inode->v.i_sb->s_fs_info;
331
332         return bch2_xattr_set(c, inode, name, value, size, flags,
333                               handler->flags);
334 }
335
336 static const struct xattr_handler bch_xattr_user_handler = {
337         .prefix = XATTR_USER_PREFIX,
338         .get    = bch2_xattr_get_handler,
339         .set    = bch2_xattr_set_handler,
340         .flags  = BCH_XATTR_INDEX_USER,
341 };
342
343 static bool bch2_xattr_trusted_list(struct dentry *dentry)
344 {
345         return capable(CAP_SYS_ADMIN);
346 }
347
348 static const struct xattr_handler bch_xattr_trusted_handler = {
349         .prefix = XATTR_TRUSTED_PREFIX,
350         .list   = bch2_xattr_trusted_list,
351         .get    = bch2_xattr_get_handler,
352         .set    = bch2_xattr_set_handler,
353         .flags  = BCH_XATTR_INDEX_TRUSTED,
354 };
355
356 static const struct xattr_handler bch_xattr_security_handler = {
357         .prefix = XATTR_SECURITY_PREFIX,
358         .get    = bch2_xattr_get_handler,
359         .set    = bch2_xattr_set_handler,
360         .flags  = BCH_XATTR_INDEX_SECURITY,
361 };
362
363 #ifndef NO_BCACHEFS_FS
364
365 static int bch2_xattr_bcachefs_get(const struct xattr_handler *handler,
366                                    struct dentry *dentry, struct inode *vinode,
367                                    const char *name, void *buffer, size_t size)
368 {
369         struct bch_inode_info *inode = to_bch_ei(vinode);
370         struct bch_fs *c = inode->v.i_sb->s_fs_info;
371         struct bch_opts opts =
372                 bch2_inode_opts_to_opts(bch2_inode_opts_get(&inode->ei_inode));
373         const struct bch_option *opt;
374         int ret, id;
375         u64 v;
376
377         id = bch2_opt_lookup(name);
378         if (id < 0 || !bch2_opt_is_inode_opt(id))
379                 return -EINVAL;
380
381         opt = bch2_opt_table + id;
382
383         if (!bch2_opt_defined_by_id(&opts, id))
384                 return -ENODATA;
385
386         v = bch2_opt_get_by_id(&opts, id);
387
388         ret = bch2_opt_to_text(c, buffer, size, opt, v, 0);
389
390         return ret < size || !buffer ? ret : -ERANGE;
391 }
392
393 struct inode_opt_set {
394         int                     id;
395         u64                     v;
396         bool                    defined;
397 };
398
399 static int inode_opt_set_fn(struct bch_inode_info *inode,
400                             struct bch_inode_unpacked *bi,
401                             void *p)
402 {
403         struct inode_opt_set *s = p;
404
405         if (s->defined)
406                 bch2_inode_opt_set(bi, s->id, s->v);
407         else
408                 bch2_inode_opt_clear(bi, s->id);
409         return 0;
410 }
411
412 static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
413                                    struct dentry *dentry, struct inode *vinode,
414                                    const char *name, const void *value,
415                                    size_t size, int flags)
416 {
417         struct bch_inode_info *inode = to_bch_ei(vinode);
418         struct bch_fs *c = inode->v.i_sb->s_fs_info;
419         const struct bch_option *opt;
420         char *buf;
421         struct inode_opt_set s;
422         int ret;
423
424         s.id = bch2_opt_lookup(name);
425         if (s.id < 0 || !bch2_opt_is_inode_opt(s.id))
426                 return -EINVAL;
427
428         opt = bch2_opt_table + s.id;
429
430         if (value) {
431                 buf = kmalloc(size + 1, GFP_KERNEL);
432                 if (!buf)
433                         return -ENOMEM;
434                 memcpy(buf, value, size);
435                 buf[size] = '\0';
436
437                 ret = bch2_opt_parse(c, opt, buf, &s.v);
438                 kfree(buf);
439
440                 if (ret < 0)
441                         return ret;
442
443                 if (s.id == Opt_compression ||
444                     s.id == Opt_background_compression) {
445                         ret = bch2_check_set_has_compressed_data(c, s.v);
446                         if (ret)
447                                 return ret;
448                 }
449
450                 s.defined = true;
451         } else {
452                 s.defined = false;
453         }
454
455         mutex_lock(&inode->ei_update_lock);
456         ret = __bch2_write_inode(c, inode, inode_opt_set_fn, &s);
457         mutex_unlock(&inode->ei_update_lock);
458
459         if (value &&
460             (s.id == Opt_background_compression ||
461              s.id == Opt_background_target))
462                 bch2_rebalance_add_work(c, inode->v.i_blocks);
463
464         return ret;
465 }
466
467 static const struct xattr_handler bch_xattr_bcachefs_handler = {
468         .prefix = "bcachefs.",
469         .get    = bch2_xattr_bcachefs_get,
470         .set    = bch2_xattr_bcachefs_set,
471 };
472
473 #endif /* NO_BCACHEFS_FS */
474
475 const struct xattr_handler *bch2_xattr_handlers[] = {
476         &bch_xattr_user_handler,
477         &posix_acl_access_xattr_handler,
478         &posix_acl_default_xattr_handler,
479         &bch_xattr_trusted_handler,
480         &bch_xattr_security_handler,
481 #ifndef NO_BCACHEFS_FS
482         &bch_xattr_bcachefs_handler,
483 #endif
484         NULL
485 };
486
487 static const struct xattr_handler *bch_xattr_handler_map[] = {
488         [BCH_XATTR_INDEX_USER]                  = &bch_xattr_user_handler,
489         [BCH_XATTR_INDEX_POSIX_ACL_ACCESS]      =
490                 &posix_acl_access_xattr_handler,
491         [BCH_XATTR_INDEX_POSIX_ACL_DEFAULT]     =
492                 &posix_acl_default_xattr_handler,
493         [BCH_XATTR_INDEX_TRUSTED]               = &bch_xattr_trusted_handler,
494         [BCH_XATTR_INDEX_SECURITY]              = &bch_xattr_security_handler,
495 };
496
497 static const struct xattr_handler *bch2_xattr_type_to_handler(unsigned type)
498 {
499         return type < ARRAY_SIZE(bch_xattr_handler_map)
500                 ? bch_xattr_handler_map[type]
501                 : NULL;
502 }