net: ipa: fix modem LAN RX endpoint id
[linux-2.6-microblaze.git] / fs / ceph / xattr.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ceph/ceph_debug.h>
3 #include <linux/ceph/pagelist.h>
4
5 #include "super.h"
6 #include "mds_client.h"
7
8 #include <linux/ceph/decode.h>
9
10 #include <linux/xattr.h>
11 #include <linux/security.h>
12 #include <linux/posix_acl_xattr.h>
13 #include <linux/slab.h>
14
15 #define XATTR_CEPH_PREFIX "ceph."
16 #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1)
17
18 static int __remove_xattr(struct ceph_inode_info *ci,
19                           struct ceph_inode_xattr *xattr);
20
21 static bool ceph_is_valid_xattr(const char *name)
22 {
23         return !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
24                !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) ||
25                !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
26                !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
27 }
28
29 /*
30  * These define virtual xattrs exposing the recursive directory
31  * statistics and layout metadata.
32  */
33 struct ceph_vxattr {
34         char *name;
35         size_t name_size;       /* strlen(name) + 1 (for '\0') */
36         ssize_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
37                                size_t size);
38         bool (*exists_cb)(struct ceph_inode_info *ci);
39         unsigned int flags;
40 };
41
42 #define VXATTR_FLAG_READONLY            (1<<0)
43 #define VXATTR_FLAG_HIDDEN              (1<<1)
44 #define VXATTR_FLAG_RSTAT               (1<<2)
45
46 /* layouts */
47
48 static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci)
49 {
50         struct ceph_file_layout *fl = &ci->i_layout;
51         return (fl->stripe_unit > 0 || fl->stripe_count > 0 ||
52                 fl->object_size > 0 || fl->pool_id >= 0 ||
53                 rcu_dereference_raw(fl->pool_ns) != NULL);
54 }
55
56 static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
57                                     size_t size)
58 {
59         struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
60         struct ceph_osd_client *osdc = &fsc->client->osdc;
61         struct ceph_string *pool_ns;
62         s64 pool = ci->i_layout.pool_id;
63         const char *pool_name;
64         const char *ns_field = " pool_namespace=";
65         char buf[128];
66         size_t len, total_len = 0;
67         ssize_t ret;
68
69         pool_ns = ceph_try_get_string(ci->i_layout.pool_ns);
70
71         dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode);
72         down_read(&osdc->lock);
73         pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
74         if (pool_name) {
75                 len = snprintf(buf, sizeof(buf),
76                 "stripe_unit=%u stripe_count=%u object_size=%u pool=",
77                 ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
78                 ci->i_layout.object_size);
79                 total_len = len + strlen(pool_name);
80         } else {
81                 len = snprintf(buf, sizeof(buf),
82                 "stripe_unit=%u stripe_count=%u object_size=%u pool=%lld",
83                 ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
84                 ci->i_layout.object_size, pool);
85                 total_len = len;
86         }
87
88         if (pool_ns)
89                 total_len += strlen(ns_field) + pool_ns->len;
90
91         ret = total_len;
92         if (size >= total_len) {
93                 memcpy(val, buf, len);
94                 ret = len;
95                 if (pool_name) {
96                         len = strlen(pool_name);
97                         memcpy(val + ret, pool_name, len);
98                         ret += len;
99                 }
100                 if (pool_ns) {
101                         len = strlen(ns_field);
102                         memcpy(val + ret, ns_field, len);
103                         ret += len;
104                         memcpy(val + ret, pool_ns->str, pool_ns->len);
105                         ret += pool_ns->len;
106                 }
107         }
108         up_read(&osdc->lock);
109         ceph_put_string(pool_ns);
110         return ret;
111 }
112
113 /*
114  * The convention with strings in xattrs is that they should not be NULL
115  * terminated, since we're returning the length with them. snprintf always
116  * NULL terminates however, so call it on a temporary buffer and then memcpy
117  * the result into place.
118  */
119 static int ceph_fmt_xattr(char *val, size_t size, const char *fmt, ...)
120 {
121         int ret;
122         va_list args;
123         char buf[96]; /* NB: reevaluate size if new vxattrs are added */
124
125         va_start(args, fmt);
126         ret = vsnprintf(buf, size ? sizeof(buf) : 0, fmt, args);
127         va_end(args);
128
129         /* Sanity check */
130         if (size && ret + 1 > sizeof(buf)) {
131                 WARN_ONCE(true, "Returned length too big (%d)", ret);
132                 return -E2BIG;
133         }
134
135         if (ret <= size)
136                 memcpy(val, buf, ret);
137         return ret;
138 }
139
140 static ssize_t ceph_vxattrcb_layout_stripe_unit(struct ceph_inode_info *ci,
141                                                 char *val, size_t size)
142 {
143         return ceph_fmt_xattr(val, size, "%u", ci->i_layout.stripe_unit);
144 }
145
146 static ssize_t ceph_vxattrcb_layout_stripe_count(struct ceph_inode_info *ci,
147                                                  char *val, size_t size)
148 {
149         return ceph_fmt_xattr(val, size, "%u", ci->i_layout.stripe_count);
150 }
151
152 static ssize_t ceph_vxattrcb_layout_object_size(struct ceph_inode_info *ci,
153                                                 char *val, size_t size)
154 {
155         return ceph_fmt_xattr(val, size, "%u", ci->i_layout.object_size);
156 }
157
158 static ssize_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci,
159                                          char *val, size_t size)
160 {
161         ssize_t ret;
162         struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
163         struct ceph_osd_client *osdc = &fsc->client->osdc;
164         s64 pool = ci->i_layout.pool_id;
165         const char *pool_name;
166
167         down_read(&osdc->lock);
168         pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
169         if (pool_name) {
170                 ret = strlen(pool_name);
171                 if (ret <= size)
172                         memcpy(val, pool_name, ret);
173         } else {
174                 ret = ceph_fmt_xattr(val, size, "%lld", pool);
175         }
176         up_read(&osdc->lock);
177         return ret;
178 }
179
180 static ssize_t ceph_vxattrcb_layout_pool_namespace(struct ceph_inode_info *ci,
181                                                    char *val, size_t size)
182 {
183         ssize_t ret = 0;
184         struct ceph_string *ns = ceph_try_get_string(ci->i_layout.pool_ns);
185
186         if (ns) {
187                 ret = ns->len;
188                 if (ret <= size)
189                         memcpy(val, ns->str, ret);
190                 ceph_put_string(ns);
191         }
192         return ret;
193 }
194
195 /* directories */
196
197 static ssize_t ceph_vxattrcb_dir_entries(struct ceph_inode_info *ci, char *val,
198                                          size_t size)
199 {
200         return ceph_fmt_xattr(val, size, "%lld", ci->i_files + ci->i_subdirs);
201 }
202
203 static ssize_t ceph_vxattrcb_dir_files(struct ceph_inode_info *ci, char *val,
204                                        size_t size)
205 {
206         return ceph_fmt_xattr(val, size, "%lld", ci->i_files);
207 }
208
209 static ssize_t ceph_vxattrcb_dir_subdirs(struct ceph_inode_info *ci, char *val,
210                                          size_t size)
211 {
212         return ceph_fmt_xattr(val, size, "%lld", ci->i_subdirs);
213 }
214
215 static ssize_t ceph_vxattrcb_dir_rentries(struct ceph_inode_info *ci, char *val,
216                                           size_t size)
217 {
218         return ceph_fmt_xattr(val, size, "%lld",
219                                 ci->i_rfiles + ci->i_rsubdirs);
220 }
221
222 static ssize_t ceph_vxattrcb_dir_rfiles(struct ceph_inode_info *ci, char *val,
223                                         size_t size)
224 {
225         return ceph_fmt_xattr(val, size, "%lld", ci->i_rfiles);
226 }
227
228 static ssize_t ceph_vxattrcb_dir_rsubdirs(struct ceph_inode_info *ci, char *val,
229                                           size_t size)
230 {
231         return ceph_fmt_xattr(val, size, "%lld", ci->i_rsubdirs);
232 }
233
234 static ssize_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info *ci, char *val,
235                                         size_t size)
236 {
237         return ceph_fmt_xattr(val, size, "%lld", ci->i_rbytes);
238 }
239
240 static ssize_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
241                                         size_t size)
242 {
243         return ceph_fmt_xattr(val, size, "%lld.%09ld", ci->i_rctime.tv_sec,
244                                 ci->i_rctime.tv_nsec);
245 }
246
247 /* dir pin */
248 static bool ceph_vxattrcb_dir_pin_exists(struct ceph_inode_info *ci)
249 {
250         return ci->i_dir_pin != -ENODATA;
251 }
252
253 static ssize_t ceph_vxattrcb_dir_pin(struct ceph_inode_info *ci, char *val,
254                                      size_t size)
255 {
256         return ceph_fmt_xattr(val, size, "%d", (int)ci->i_dir_pin);
257 }
258
259 /* quotas */
260 static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
261 {
262         bool ret = false;
263         spin_lock(&ci->i_ceph_lock);
264         if ((ci->i_max_files || ci->i_max_bytes) &&
265             ci->i_vino.snap == CEPH_NOSNAP &&
266             ci->i_snap_realm &&
267             ci->i_snap_realm->ino == ci->i_vino.ino)
268                 ret = true;
269         spin_unlock(&ci->i_ceph_lock);
270         return ret;
271 }
272
273 static ssize_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val,
274                                    size_t size)
275 {
276         return ceph_fmt_xattr(val, size, "max_bytes=%llu max_files=%llu",
277                                 ci->i_max_bytes, ci->i_max_files);
278 }
279
280 static ssize_t ceph_vxattrcb_quota_max_bytes(struct ceph_inode_info *ci,
281                                              char *val, size_t size)
282 {
283         return ceph_fmt_xattr(val, size, "%llu", ci->i_max_bytes);
284 }
285
286 static ssize_t ceph_vxattrcb_quota_max_files(struct ceph_inode_info *ci,
287                                              char *val, size_t size)
288 {
289         return ceph_fmt_xattr(val, size, "%llu", ci->i_max_files);
290 }
291
292 /* snapshots */
293 static bool ceph_vxattrcb_snap_btime_exists(struct ceph_inode_info *ci)
294 {
295         return (ci->i_snap_btime.tv_sec != 0 || ci->i_snap_btime.tv_nsec != 0);
296 }
297
298 static ssize_t ceph_vxattrcb_snap_btime(struct ceph_inode_info *ci, char *val,
299                                         size_t size)
300 {
301         return ceph_fmt_xattr(val, size, "%lld.%09ld", ci->i_snap_btime.tv_sec,
302                                 ci->i_snap_btime.tv_nsec);
303 }
304
305 #define CEPH_XATTR_NAME(_type, _name)   XATTR_CEPH_PREFIX #_type "." #_name
306 #define CEPH_XATTR_NAME2(_type, _name, _name2)  \
307         XATTR_CEPH_PREFIX #_type "." #_name "." #_name2
308
309 #define XATTR_NAME_CEPH(_type, _name, _flags)                           \
310         {                                                               \
311                 .name = CEPH_XATTR_NAME(_type, _name),                  \
312                 .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
313                 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
314                 .exists_cb = NULL,                                      \
315                 .flags = (VXATTR_FLAG_READONLY | _flags),               \
316         }
317 #define XATTR_RSTAT_FIELD(_type, _name)                 \
318         XATTR_NAME_CEPH(_type, _name, VXATTR_FLAG_RSTAT)
319 #define XATTR_LAYOUT_FIELD(_type, _name, _field)                        \
320         {                                                               \
321                 .name = CEPH_XATTR_NAME2(_type, _name, _field), \
322                 .name_size = sizeof (CEPH_XATTR_NAME2(_type, _name, _field)), \
323                 .getxattr_cb = ceph_vxattrcb_ ## _name ## _ ## _field, \
324                 .exists_cb = ceph_vxattrcb_layout_exists,       \
325                 .flags = VXATTR_FLAG_HIDDEN,                    \
326         }
327 #define XATTR_QUOTA_FIELD(_type, _name)                                 \
328         {                                                               \
329                 .name = CEPH_XATTR_NAME(_type, _name),                  \
330                 .name_size = sizeof(CEPH_XATTR_NAME(_type, _name)),     \
331                 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name,   \
332                 .exists_cb = ceph_vxattrcb_quota_exists,                \
333                 .flags = VXATTR_FLAG_HIDDEN,                            \
334         }
335
336 static struct ceph_vxattr ceph_dir_vxattrs[] = {
337         {
338                 .name = "ceph.dir.layout",
339                 .name_size = sizeof("ceph.dir.layout"),
340                 .getxattr_cb = ceph_vxattrcb_layout,
341                 .exists_cb = ceph_vxattrcb_layout_exists,
342                 .flags = VXATTR_FLAG_HIDDEN,
343         },
344         XATTR_LAYOUT_FIELD(dir, layout, stripe_unit),
345         XATTR_LAYOUT_FIELD(dir, layout, stripe_count),
346         XATTR_LAYOUT_FIELD(dir, layout, object_size),
347         XATTR_LAYOUT_FIELD(dir, layout, pool),
348         XATTR_LAYOUT_FIELD(dir, layout, pool_namespace),
349         XATTR_NAME_CEPH(dir, entries, 0),
350         XATTR_NAME_CEPH(dir, files, 0),
351         XATTR_NAME_CEPH(dir, subdirs, 0),
352         XATTR_RSTAT_FIELD(dir, rentries),
353         XATTR_RSTAT_FIELD(dir, rfiles),
354         XATTR_RSTAT_FIELD(dir, rsubdirs),
355         XATTR_RSTAT_FIELD(dir, rbytes),
356         XATTR_RSTAT_FIELD(dir, rctime),
357         {
358                 .name = "ceph.dir.pin",
359                 .name_size = sizeof("ceph.dir.pin"),
360                 .getxattr_cb = ceph_vxattrcb_dir_pin,
361                 .exists_cb = ceph_vxattrcb_dir_pin_exists,
362                 .flags = VXATTR_FLAG_HIDDEN,
363         },
364         {
365                 .name = "ceph.quota",
366                 .name_size = sizeof("ceph.quota"),
367                 .getxattr_cb = ceph_vxattrcb_quota,
368                 .exists_cb = ceph_vxattrcb_quota_exists,
369                 .flags = VXATTR_FLAG_HIDDEN,
370         },
371         XATTR_QUOTA_FIELD(quota, max_bytes),
372         XATTR_QUOTA_FIELD(quota, max_files),
373         {
374                 .name = "ceph.snap.btime",
375                 .name_size = sizeof("ceph.snap.btime"),
376                 .getxattr_cb = ceph_vxattrcb_snap_btime,
377                 .exists_cb = ceph_vxattrcb_snap_btime_exists,
378                 .flags = VXATTR_FLAG_READONLY,
379         },
380         { .name = NULL, 0 }     /* Required table terminator */
381 };
382
383 /* files */
384
385 static struct ceph_vxattr ceph_file_vxattrs[] = {
386         {
387                 .name = "ceph.file.layout",
388                 .name_size = sizeof("ceph.file.layout"),
389                 .getxattr_cb = ceph_vxattrcb_layout,
390                 .exists_cb = ceph_vxattrcb_layout_exists,
391                 .flags = VXATTR_FLAG_HIDDEN,
392         },
393         XATTR_LAYOUT_FIELD(file, layout, stripe_unit),
394         XATTR_LAYOUT_FIELD(file, layout, stripe_count),
395         XATTR_LAYOUT_FIELD(file, layout, object_size),
396         XATTR_LAYOUT_FIELD(file, layout, pool),
397         XATTR_LAYOUT_FIELD(file, layout, pool_namespace),
398         {
399                 .name = "ceph.snap.btime",
400                 .name_size = sizeof("ceph.snap.btime"),
401                 .getxattr_cb = ceph_vxattrcb_snap_btime,
402                 .exists_cb = ceph_vxattrcb_snap_btime_exists,
403                 .flags = VXATTR_FLAG_READONLY,
404         },
405         { .name = NULL, 0 }     /* Required table terminator */
406 };
407
408 static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
409 {
410         if (S_ISDIR(inode->i_mode))
411                 return ceph_dir_vxattrs;
412         else if (S_ISREG(inode->i_mode))
413                 return ceph_file_vxattrs;
414         return NULL;
415 }
416
417 static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
418                                                 const char *name)
419 {
420         struct ceph_vxattr *vxattr = ceph_inode_vxattrs(inode);
421
422         if (vxattr) {
423                 while (vxattr->name) {
424                         if (!strcmp(vxattr->name, name))
425                                 return vxattr;
426                         vxattr++;
427                 }
428         }
429
430         return NULL;
431 }
432
433 static int __set_xattr(struct ceph_inode_info *ci,
434                            const char *name, int name_len,
435                            const char *val, int val_len,
436                            int flags, int update_xattr,
437                            struct ceph_inode_xattr **newxattr)
438 {
439         struct rb_node **p;
440         struct rb_node *parent = NULL;
441         struct ceph_inode_xattr *xattr = NULL;
442         int c;
443         int new = 0;
444
445         p = &ci->i_xattrs.index.rb_node;
446         while (*p) {
447                 parent = *p;
448                 xattr = rb_entry(parent, struct ceph_inode_xattr, node);
449                 c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
450                 if (c < 0)
451                         p = &(*p)->rb_left;
452                 else if (c > 0)
453                         p = &(*p)->rb_right;
454                 else {
455                         if (name_len == xattr->name_len)
456                                 break;
457                         else if (name_len < xattr->name_len)
458                                 p = &(*p)->rb_left;
459                         else
460                                 p = &(*p)->rb_right;
461                 }
462                 xattr = NULL;
463         }
464
465         if (update_xattr) {
466                 int err = 0;
467
468                 if (xattr && (flags & XATTR_CREATE))
469                         err = -EEXIST;
470                 else if (!xattr && (flags & XATTR_REPLACE))
471                         err = -ENODATA;
472                 if (err) {
473                         kfree(name);
474                         kfree(val);
475                         kfree(*newxattr);
476                         return err;
477                 }
478                 if (update_xattr < 0) {
479                         if (xattr)
480                                 __remove_xattr(ci, xattr);
481                         kfree(name);
482                         kfree(*newxattr);
483                         return 0;
484                 }
485         }
486
487         if (!xattr) {
488                 new = 1;
489                 xattr = *newxattr;
490                 xattr->name = name;
491                 xattr->name_len = name_len;
492                 xattr->should_free_name = update_xattr;
493
494                 ci->i_xattrs.count++;
495                 dout("__set_xattr count=%d\n", ci->i_xattrs.count);
496         } else {
497                 kfree(*newxattr);
498                 *newxattr = NULL;
499                 if (xattr->should_free_val)
500                         kfree((void *)xattr->val);
501
502                 if (update_xattr) {
503                         kfree((void *)name);
504                         name = xattr->name;
505                 }
506                 ci->i_xattrs.names_size -= xattr->name_len;
507                 ci->i_xattrs.vals_size -= xattr->val_len;
508         }
509         ci->i_xattrs.names_size += name_len;
510         ci->i_xattrs.vals_size += val_len;
511         if (val)
512                 xattr->val = val;
513         else
514                 xattr->val = "";
515
516         xattr->val_len = val_len;
517         xattr->dirty = update_xattr;
518         xattr->should_free_val = (val && update_xattr);
519
520         if (new) {
521                 rb_link_node(&xattr->node, parent, p);
522                 rb_insert_color(&xattr->node, &ci->i_xattrs.index);
523                 dout("__set_xattr_val p=%p\n", p);
524         }
525
526         dout("__set_xattr_val added %llx.%llx xattr %p %.*s=%.*s\n",
527              ceph_vinop(&ci->vfs_inode), xattr, name_len, name, val_len, val);
528
529         return 0;
530 }
531
532 static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
533                            const char *name)
534 {
535         struct rb_node **p;
536         struct rb_node *parent = NULL;
537         struct ceph_inode_xattr *xattr = NULL;
538         int name_len = strlen(name);
539         int c;
540
541         p = &ci->i_xattrs.index.rb_node;
542         while (*p) {
543                 parent = *p;
544                 xattr = rb_entry(parent, struct ceph_inode_xattr, node);
545                 c = strncmp(name, xattr->name, xattr->name_len);
546                 if (c == 0 && name_len > xattr->name_len)
547                         c = 1;
548                 if (c < 0)
549                         p = &(*p)->rb_left;
550                 else if (c > 0)
551                         p = &(*p)->rb_right;
552                 else {
553                         dout("__get_xattr %s: found %.*s\n", name,
554                              xattr->val_len, xattr->val);
555                         return xattr;
556                 }
557         }
558
559         dout("__get_xattr %s: not found\n", name);
560
561         return NULL;
562 }
563
564 static void __free_xattr(struct ceph_inode_xattr *xattr)
565 {
566         BUG_ON(!xattr);
567
568         if (xattr->should_free_name)
569                 kfree((void *)xattr->name);
570         if (xattr->should_free_val)
571                 kfree((void *)xattr->val);
572
573         kfree(xattr);
574 }
575
576 static int __remove_xattr(struct ceph_inode_info *ci,
577                           struct ceph_inode_xattr *xattr)
578 {
579         if (!xattr)
580                 return -ENODATA;
581
582         rb_erase(&xattr->node, &ci->i_xattrs.index);
583
584         if (xattr->should_free_name)
585                 kfree((void *)xattr->name);
586         if (xattr->should_free_val)
587                 kfree((void *)xattr->val);
588
589         ci->i_xattrs.names_size -= xattr->name_len;
590         ci->i_xattrs.vals_size -= xattr->val_len;
591         ci->i_xattrs.count--;
592         kfree(xattr);
593
594         return 0;
595 }
596
597 static char *__copy_xattr_names(struct ceph_inode_info *ci,
598                                 char *dest)
599 {
600         struct rb_node *p;
601         struct ceph_inode_xattr *xattr = NULL;
602
603         p = rb_first(&ci->i_xattrs.index);
604         dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
605
606         while (p) {
607                 xattr = rb_entry(p, struct ceph_inode_xattr, node);
608                 memcpy(dest, xattr->name, xattr->name_len);
609                 dest[xattr->name_len] = '\0';
610
611                 dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
612                      xattr->name_len, ci->i_xattrs.names_size);
613
614                 dest += xattr->name_len + 1;
615                 p = rb_next(p);
616         }
617
618         return dest;
619 }
620
621 void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
622 {
623         struct rb_node *p, *tmp;
624         struct ceph_inode_xattr *xattr = NULL;
625
626         p = rb_first(&ci->i_xattrs.index);
627
628         dout("__ceph_destroy_xattrs p=%p\n", p);
629
630         while (p) {
631                 xattr = rb_entry(p, struct ceph_inode_xattr, node);
632                 tmp = p;
633                 p = rb_next(tmp);
634                 dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
635                      xattr->name_len, xattr->name);
636                 rb_erase(tmp, &ci->i_xattrs.index);
637
638                 __free_xattr(xattr);
639         }
640
641         ci->i_xattrs.names_size = 0;
642         ci->i_xattrs.vals_size = 0;
643         ci->i_xattrs.index_version = 0;
644         ci->i_xattrs.count = 0;
645         ci->i_xattrs.index = RB_ROOT;
646 }
647
648 static int __build_xattrs(struct inode *inode)
649         __releases(ci->i_ceph_lock)
650         __acquires(ci->i_ceph_lock)
651 {
652         u32 namelen;
653         u32 numattr = 0;
654         void *p, *end;
655         u32 len;
656         const char *name, *val;
657         struct ceph_inode_info *ci = ceph_inode(inode);
658         u64 xattr_version;
659         struct ceph_inode_xattr **xattrs = NULL;
660         int err = 0;
661         int i;
662
663         dout("__build_xattrs() len=%d\n",
664              ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
665
666         if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
667                 return 0; /* already built */
668
669         __ceph_destroy_xattrs(ci);
670
671 start:
672         /* updated internal xattr rb tree */
673         if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
674                 p = ci->i_xattrs.blob->vec.iov_base;
675                 end = p + ci->i_xattrs.blob->vec.iov_len;
676                 ceph_decode_32_safe(&p, end, numattr, bad);
677                 xattr_version = ci->i_xattrs.version;
678                 spin_unlock(&ci->i_ceph_lock);
679
680                 xattrs = kcalloc(numattr, sizeof(struct ceph_inode_xattr *),
681                                  GFP_NOFS);
682                 err = -ENOMEM;
683                 if (!xattrs)
684                         goto bad_lock;
685
686                 for (i = 0; i < numattr; i++) {
687                         xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
688                                             GFP_NOFS);
689                         if (!xattrs[i])
690                                 goto bad_lock;
691                 }
692
693                 spin_lock(&ci->i_ceph_lock);
694                 if (ci->i_xattrs.version != xattr_version) {
695                         /* lost a race, retry */
696                         for (i = 0; i < numattr; i++)
697                                 kfree(xattrs[i]);
698                         kfree(xattrs);
699                         xattrs = NULL;
700                         goto start;
701                 }
702                 err = -EIO;
703                 while (numattr--) {
704                         ceph_decode_32_safe(&p, end, len, bad);
705                         namelen = len;
706                         name = p;
707                         p += len;
708                         ceph_decode_32_safe(&p, end, len, bad);
709                         val = p;
710                         p += len;
711
712                         err = __set_xattr(ci, name, namelen, val, len,
713                                           0, 0, &xattrs[numattr]);
714
715                         if (err < 0)
716                                 goto bad;
717                 }
718                 kfree(xattrs);
719         }
720         ci->i_xattrs.index_version = ci->i_xattrs.version;
721         ci->i_xattrs.dirty = false;
722
723         return err;
724 bad_lock:
725         spin_lock(&ci->i_ceph_lock);
726 bad:
727         if (xattrs) {
728                 for (i = 0; i < numattr; i++)
729                         kfree(xattrs[i]);
730                 kfree(xattrs);
731         }
732         ci->i_xattrs.names_size = 0;
733         return err;
734 }
735
736 static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
737                                     int val_size)
738 {
739         /*
740          * 4 bytes for the length, and additional 4 bytes per each xattr name,
741          * 4 bytes per each value
742          */
743         int size = 4 + ci->i_xattrs.count*(4 + 4) +
744                              ci->i_xattrs.names_size +
745                              ci->i_xattrs.vals_size;
746         dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
747              ci->i_xattrs.count, ci->i_xattrs.names_size,
748              ci->i_xattrs.vals_size);
749
750         if (name_size)
751                 size += 4 + 4 + name_size + val_size;
752
753         return size;
754 }
755
756 /*
757  * If there are dirty xattrs, reencode xattrs into the prealloc_blob
758  * and swap into place.  It returns the old i_xattrs.blob (or NULL) so
759  * that it can be freed by the caller as the i_ceph_lock is likely to be
760  * held.
761  */
762 struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci)
763 {
764         struct rb_node *p;
765         struct ceph_inode_xattr *xattr = NULL;
766         struct ceph_buffer *old_blob = NULL;
767         void *dest;
768
769         dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
770         if (ci->i_xattrs.dirty) {
771                 int need = __get_required_blob_size(ci, 0, 0);
772
773                 BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
774
775                 p = rb_first(&ci->i_xattrs.index);
776                 dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
777
778                 ceph_encode_32(&dest, ci->i_xattrs.count);
779                 while (p) {
780                         xattr = rb_entry(p, struct ceph_inode_xattr, node);
781
782                         ceph_encode_32(&dest, xattr->name_len);
783                         memcpy(dest, xattr->name, xattr->name_len);
784                         dest += xattr->name_len;
785                         ceph_encode_32(&dest, xattr->val_len);
786                         memcpy(dest, xattr->val, xattr->val_len);
787                         dest += xattr->val_len;
788
789                         p = rb_next(p);
790                 }
791
792                 /* adjust buffer len; it may be larger than we need */
793                 ci->i_xattrs.prealloc_blob->vec.iov_len =
794                         dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
795
796                 if (ci->i_xattrs.blob)
797                         old_blob = ci->i_xattrs.blob;
798                 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
799                 ci->i_xattrs.prealloc_blob = NULL;
800                 ci->i_xattrs.dirty = false;
801                 ci->i_xattrs.version++;
802         }
803
804         return old_blob;
805 }
806
807 static inline int __get_request_mask(struct inode *in) {
808         struct ceph_mds_request *req = current->journal_info;
809         int mask = 0;
810         if (req && req->r_target_inode == in) {
811                 if (req->r_op == CEPH_MDS_OP_LOOKUP ||
812                     req->r_op == CEPH_MDS_OP_LOOKUPINO ||
813                     req->r_op == CEPH_MDS_OP_LOOKUPPARENT ||
814                     req->r_op == CEPH_MDS_OP_GETATTR) {
815                         mask = le32_to_cpu(req->r_args.getattr.mask);
816                 } else if (req->r_op == CEPH_MDS_OP_OPEN ||
817                            req->r_op == CEPH_MDS_OP_CREATE) {
818                         mask = le32_to_cpu(req->r_args.open.mask);
819                 }
820         }
821         return mask;
822 }
823
824 ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
825                       size_t size)
826 {
827         struct ceph_inode_info *ci = ceph_inode(inode);
828         struct ceph_inode_xattr *xattr;
829         struct ceph_vxattr *vxattr = NULL;
830         int req_mask;
831         ssize_t err;
832
833         /* let's see if a virtual xattr was requested */
834         vxattr = ceph_match_vxattr(inode, name);
835         if (vxattr) {
836                 int mask = 0;
837                 if (vxattr->flags & VXATTR_FLAG_RSTAT)
838                         mask |= CEPH_STAT_RSTAT;
839                 err = ceph_do_getattr(inode, mask, true);
840                 if (err)
841                         return err;
842                 err = -ENODATA;
843                 if (!(vxattr->exists_cb && !vxattr->exists_cb(ci))) {
844                         err = vxattr->getxattr_cb(ci, value, size);
845                         if (size && size < err)
846                                 err = -ERANGE;
847                 }
848                 return err;
849         }
850
851         req_mask = __get_request_mask(inode);
852
853         spin_lock(&ci->i_ceph_lock);
854         dout("getxattr %p name '%s' ver=%lld index_ver=%lld\n", inode, name,
855              ci->i_xattrs.version, ci->i_xattrs.index_version);
856
857         if (ci->i_xattrs.version == 0 ||
858             !((req_mask & CEPH_CAP_XATTR_SHARED) ||
859               __ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1))) {
860                 spin_unlock(&ci->i_ceph_lock);
861
862                 /* security module gets xattr while filling trace */
863                 if (current->journal_info) {
864                         pr_warn_ratelimited("sync getxattr %p "
865                                             "during filling trace\n", inode);
866                         return -EBUSY;
867                 }
868
869                 /* get xattrs from mds (if we don't already have them) */
870                 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
871                 if (err)
872                         return err;
873                 spin_lock(&ci->i_ceph_lock);
874         }
875
876         err = __build_xattrs(inode);
877         if (err < 0)
878                 goto out;
879
880         err = -ENODATA;  /* == ENOATTR */
881         xattr = __get_xattr(ci, name);
882         if (!xattr)
883                 goto out;
884
885         err = -ERANGE;
886         if (size && size < xattr->val_len)
887                 goto out;
888
889         err = xattr->val_len;
890         if (size == 0)
891                 goto out;
892
893         memcpy(value, xattr->val, xattr->val_len);
894
895         if (current->journal_info &&
896             !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
897             security_ismaclabel(name + XATTR_SECURITY_PREFIX_LEN))
898                 ci->i_ceph_flags |= CEPH_I_SEC_INITED;
899 out:
900         spin_unlock(&ci->i_ceph_lock);
901         return err;
902 }
903
904 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
905 {
906         struct inode *inode = d_inode(dentry);
907         struct ceph_inode_info *ci = ceph_inode(inode);
908         bool len_only = (size == 0);
909         u32 namelen;
910         int err;
911
912         spin_lock(&ci->i_ceph_lock);
913         dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
914              ci->i_xattrs.version, ci->i_xattrs.index_version);
915
916         if (ci->i_xattrs.version == 0 ||
917             !__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1)) {
918                 spin_unlock(&ci->i_ceph_lock);
919                 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
920                 if (err)
921                         return err;
922                 spin_lock(&ci->i_ceph_lock);
923         }
924
925         err = __build_xattrs(inode);
926         if (err < 0)
927                 goto out;
928
929         /* add 1 byte for each xattr due to the null termination */
930         namelen = ci->i_xattrs.names_size + ci->i_xattrs.count;
931         if (!len_only) {
932                 if (namelen > size) {
933                         err = -ERANGE;
934                         goto out;
935                 }
936                 names = __copy_xattr_names(ci, names);
937                 size -= namelen;
938         }
939         err = namelen;
940 out:
941         spin_unlock(&ci->i_ceph_lock);
942         return err;
943 }
944
945 static int ceph_sync_setxattr(struct inode *inode, const char *name,
946                               const char *value, size_t size, int flags)
947 {
948         struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
949         struct ceph_inode_info *ci = ceph_inode(inode);
950         struct ceph_mds_request *req;
951         struct ceph_mds_client *mdsc = fsc->mdsc;
952         struct ceph_pagelist *pagelist = NULL;
953         int op = CEPH_MDS_OP_SETXATTR;
954         int err;
955
956         if (size > 0) {
957                 /* copy value into pagelist */
958                 pagelist = ceph_pagelist_alloc(GFP_NOFS);
959                 if (!pagelist)
960                         return -ENOMEM;
961
962                 err = ceph_pagelist_append(pagelist, value, size);
963                 if (err)
964                         goto out;
965         } else if (!value) {
966                 if (flags & CEPH_XATTR_REPLACE)
967                         op = CEPH_MDS_OP_RMXATTR;
968                 else
969                         flags |= CEPH_XATTR_REMOVE;
970         }
971
972         dout("setxattr value=%.*s\n", (int)size, value);
973
974         /* do request */
975         req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
976         if (IS_ERR(req)) {
977                 err = PTR_ERR(req);
978                 goto out;
979         }
980
981         req->r_path2 = kstrdup(name, GFP_NOFS);
982         if (!req->r_path2) {
983                 ceph_mdsc_put_request(req);
984                 err = -ENOMEM;
985                 goto out;
986         }
987
988         if (op == CEPH_MDS_OP_SETXATTR) {
989                 req->r_args.setxattr.flags = cpu_to_le32(flags);
990                 req->r_pagelist = pagelist;
991                 pagelist = NULL;
992         }
993
994         req->r_inode = inode;
995         ihold(inode);
996         req->r_num_caps = 1;
997         req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
998
999         dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
1000         err = ceph_mdsc_do_request(mdsc, NULL, req);
1001         ceph_mdsc_put_request(req);
1002         dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
1003
1004 out:
1005         if (pagelist)
1006                 ceph_pagelist_release(pagelist);
1007         return err;
1008 }
1009
1010 int __ceph_setxattr(struct inode *inode, const char *name,
1011                         const void *value, size_t size, int flags)
1012 {
1013         struct ceph_vxattr *vxattr;
1014         struct ceph_inode_info *ci = ceph_inode(inode);
1015         struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
1016         struct ceph_cap_flush *prealloc_cf = NULL;
1017         struct ceph_buffer *old_blob = NULL;
1018         int issued;
1019         int err;
1020         int dirty = 0;
1021         int name_len = strlen(name);
1022         int val_len = size;
1023         char *newname = NULL;
1024         char *newval = NULL;
1025         struct ceph_inode_xattr *xattr = NULL;
1026         int required_blob_size;
1027         bool check_realm = false;
1028         bool lock_snap_rwsem = false;
1029
1030         if (ceph_snap(inode) != CEPH_NOSNAP)
1031                 return -EROFS;
1032
1033         vxattr = ceph_match_vxattr(inode, name);
1034         if (vxattr) {
1035                 if (vxattr->flags & VXATTR_FLAG_READONLY)
1036                         return -EOPNOTSUPP;
1037                 if (value && !strncmp(vxattr->name, "ceph.quota", 10))
1038                         check_realm = true;
1039         }
1040
1041         /* pass any unhandled ceph.* xattrs through to the MDS */
1042         if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
1043                 goto do_sync_unlocked;
1044
1045         /* preallocate memory for xattr name, value, index node */
1046         err = -ENOMEM;
1047         newname = kmemdup(name, name_len + 1, GFP_NOFS);
1048         if (!newname)
1049                 goto out;
1050
1051         if (val_len) {
1052                 newval = kmemdup(value, val_len, GFP_NOFS);
1053                 if (!newval)
1054                         goto out;
1055         }
1056
1057         xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
1058         if (!xattr)
1059                 goto out;
1060
1061         prealloc_cf = ceph_alloc_cap_flush();
1062         if (!prealloc_cf)
1063                 goto out;
1064
1065         spin_lock(&ci->i_ceph_lock);
1066 retry:
1067         issued = __ceph_caps_issued(ci, NULL);
1068         if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))
1069                 goto do_sync;
1070
1071         if (!lock_snap_rwsem && !ci->i_head_snapc) {
1072                 lock_snap_rwsem = true;
1073                 if (!down_read_trylock(&mdsc->snap_rwsem)) {
1074                         spin_unlock(&ci->i_ceph_lock);
1075                         down_read(&mdsc->snap_rwsem);
1076                         spin_lock(&ci->i_ceph_lock);
1077                         goto retry;
1078                 }
1079         }
1080
1081         dout("setxattr %p name '%s' issued %s\n", inode, name,
1082              ceph_cap_string(issued));
1083         __build_xattrs(inode);
1084
1085         required_blob_size = __get_required_blob_size(ci, name_len, val_len);
1086
1087         if (!ci->i_xattrs.prealloc_blob ||
1088             required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
1089                 struct ceph_buffer *blob;
1090
1091                 spin_unlock(&ci->i_ceph_lock);
1092                 ceph_buffer_put(old_blob); /* Shouldn't be required */
1093                 dout(" pre-allocating new blob size=%d\n", required_blob_size);
1094                 blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
1095                 if (!blob)
1096                         goto do_sync_unlocked;
1097                 spin_lock(&ci->i_ceph_lock);
1098                 /* prealloc_blob can't be released while holding i_ceph_lock */
1099                 if (ci->i_xattrs.prealloc_blob)
1100                         old_blob = ci->i_xattrs.prealloc_blob;
1101                 ci->i_xattrs.prealloc_blob = blob;
1102                 goto retry;
1103         }
1104
1105         err = __set_xattr(ci, newname, name_len, newval, val_len,
1106                           flags, value ? 1 : -1, &xattr);
1107
1108         if (!err) {
1109                 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL,
1110                                                &prealloc_cf);
1111                 ci->i_xattrs.dirty = true;
1112                 inode->i_ctime = current_time(inode);
1113         }
1114
1115         spin_unlock(&ci->i_ceph_lock);
1116         ceph_buffer_put(old_blob);
1117         if (lock_snap_rwsem)
1118                 up_read(&mdsc->snap_rwsem);
1119         if (dirty)
1120                 __mark_inode_dirty(inode, dirty);
1121         ceph_free_cap_flush(prealloc_cf);
1122         return err;
1123
1124 do_sync:
1125         spin_unlock(&ci->i_ceph_lock);
1126 do_sync_unlocked:
1127         if (lock_snap_rwsem)
1128                 up_read(&mdsc->snap_rwsem);
1129
1130         /* security module set xattr while filling trace */
1131         if (current->journal_info) {
1132                 pr_warn_ratelimited("sync setxattr %p "
1133                                     "during filling trace\n", inode);
1134                 err = -EBUSY;
1135         } else {
1136                 err = ceph_sync_setxattr(inode, name, value, size, flags);
1137                 if (err >= 0 && check_realm) {
1138                         /* check if snaprealm was created for quota inode */
1139                         spin_lock(&ci->i_ceph_lock);
1140                         if ((ci->i_max_files || ci->i_max_bytes) &&
1141                             !(ci->i_snap_realm &&
1142                               ci->i_snap_realm->ino == ci->i_vino.ino))
1143                                 err = -EOPNOTSUPP;
1144                         spin_unlock(&ci->i_ceph_lock);
1145                 }
1146         }
1147 out:
1148         ceph_free_cap_flush(prealloc_cf);
1149         kfree(newname);
1150         kfree(newval);
1151         kfree(xattr);
1152         return err;
1153 }
1154
1155 static int ceph_get_xattr_handler(const struct xattr_handler *handler,
1156                                   struct dentry *dentry, struct inode *inode,
1157                                   const char *name, void *value, size_t size)
1158 {
1159         if (!ceph_is_valid_xattr(name))
1160                 return -EOPNOTSUPP;
1161         return __ceph_getxattr(inode, name, value, size);
1162 }
1163
1164 static int ceph_set_xattr_handler(const struct xattr_handler *handler,
1165                                   struct dentry *unused, struct inode *inode,
1166                                   const char *name, const void *value,
1167                                   size_t size, int flags)
1168 {
1169         if (!ceph_is_valid_xattr(name))
1170                 return -EOPNOTSUPP;
1171         return __ceph_setxattr(inode, name, value, size, flags);
1172 }
1173
1174 static const struct xattr_handler ceph_other_xattr_handler = {
1175         .prefix = "",  /* match any name => handlers called with full name */
1176         .get = ceph_get_xattr_handler,
1177         .set = ceph_set_xattr_handler,
1178 };
1179
1180 #ifdef CONFIG_SECURITY
1181 bool ceph_security_xattr_wanted(struct inode *in)
1182 {
1183         return in->i_security != NULL;
1184 }
1185
1186 bool ceph_security_xattr_deadlock(struct inode *in)
1187 {
1188         struct ceph_inode_info *ci;
1189         bool ret;
1190         if (!in->i_security)
1191                 return false;
1192         ci = ceph_inode(in);
1193         spin_lock(&ci->i_ceph_lock);
1194         ret = !(ci->i_ceph_flags & CEPH_I_SEC_INITED) &&
1195               !(ci->i_xattrs.version > 0 &&
1196                 __ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 0));
1197         spin_unlock(&ci->i_ceph_lock);
1198         return ret;
1199 }
1200
1201 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1202 int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
1203                            struct ceph_acl_sec_ctx *as_ctx)
1204 {
1205         struct ceph_pagelist *pagelist = as_ctx->pagelist;
1206         const char *name;
1207         size_t name_len;
1208         int err;
1209
1210         err = security_dentry_init_security(dentry, mode, &dentry->d_name,
1211                                             &as_ctx->sec_ctx,
1212                                             &as_ctx->sec_ctxlen);
1213         if (err < 0) {
1214                 WARN_ON_ONCE(err != -EOPNOTSUPP);
1215                 err = 0; /* do nothing */
1216                 goto out;
1217         }
1218
1219         err = -ENOMEM;
1220         if (!pagelist) {
1221                 pagelist = ceph_pagelist_alloc(GFP_KERNEL);
1222                 if (!pagelist)
1223                         goto out;
1224                 err = ceph_pagelist_reserve(pagelist, PAGE_SIZE);
1225                 if (err)
1226                         goto out;
1227                 ceph_pagelist_encode_32(pagelist, 1);
1228         }
1229
1230         /*
1231          * FIXME: Make security_dentry_init_security() generic. Currently
1232          * It only supports single security module and only selinux has
1233          * dentry_init_security hook.
1234          */
1235         name = XATTR_NAME_SELINUX;
1236         name_len = strlen(name);
1237         err = ceph_pagelist_reserve(pagelist,
1238                                     4 * 2 + name_len + as_ctx->sec_ctxlen);
1239         if (err)
1240                 goto out;
1241
1242         if (as_ctx->pagelist) {
1243                 /* update count of KV pairs */
1244                 BUG_ON(pagelist->length <= sizeof(__le32));
1245                 if (list_is_singular(&pagelist->head)) {
1246                         le32_add_cpu((__le32*)pagelist->mapped_tail, 1);
1247                 } else {
1248                         struct page *page = list_first_entry(&pagelist->head,
1249                                                              struct page, lru);
1250                         void *addr = kmap_atomic(page);
1251                         le32_add_cpu((__le32*)addr, 1);
1252                         kunmap_atomic(addr);
1253                 }
1254         } else {
1255                 as_ctx->pagelist = pagelist;
1256         }
1257
1258         ceph_pagelist_encode_32(pagelist, name_len);
1259         ceph_pagelist_append(pagelist, name, name_len);
1260
1261         ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen);
1262         ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1263
1264         err = 0;
1265 out:
1266         if (pagelist && !as_ctx->pagelist)
1267                 ceph_pagelist_release(pagelist);
1268         return err;
1269 }
1270 #endif /* CONFIG_CEPH_FS_SECURITY_LABEL */
1271 #endif /* CONFIG_SECURITY */
1272
1273 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
1274 {
1275 #ifdef CONFIG_CEPH_FS_POSIX_ACL
1276         posix_acl_release(as_ctx->acl);
1277         posix_acl_release(as_ctx->default_acl);
1278 #endif
1279 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1280         security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1281 #endif
1282         if (as_ctx->pagelist)
1283                 ceph_pagelist_release(as_ctx->pagelist);
1284 }
1285
1286 /*
1287  * List of handlers for synthetic system.* attributes. Other
1288  * attributes are handled directly.
1289  */
1290 const struct xattr_handler *ceph_xattr_handlers[] = {
1291 #ifdef CONFIG_CEPH_FS_POSIX_ACL
1292         &posix_acl_access_xattr_handler,
1293         &posix_acl_default_xattr_handler,
1294 #endif
1295         &ceph_other_xattr_handler,
1296         NULL,
1297 };