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