root/fs/ceph/xattr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ceph_is_valid_xattr
  2. ceph_vxattrcb_layout_exists
  3. ceph_vxattrcb_layout
  4. ceph_fmt_xattr
  5. ceph_vxattrcb_layout_stripe_unit
  6. ceph_vxattrcb_layout_stripe_count
  7. ceph_vxattrcb_layout_object_size
  8. ceph_vxattrcb_layout_pool
  9. ceph_vxattrcb_layout_pool_namespace
  10. ceph_vxattrcb_dir_entries
  11. ceph_vxattrcb_dir_files
  12. ceph_vxattrcb_dir_subdirs
  13. ceph_vxattrcb_dir_rentries
  14. ceph_vxattrcb_dir_rfiles
  15. ceph_vxattrcb_dir_rsubdirs
  16. ceph_vxattrcb_dir_rbytes
  17. ceph_vxattrcb_dir_rctime
  18. ceph_vxattrcb_dir_pin_exists
  19. ceph_vxattrcb_dir_pin
  20. ceph_vxattrcb_quota_exists
  21. ceph_vxattrcb_quota
  22. ceph_vxattrcb_quota_max_bytes
  23. ceph_vxattrcb_quota_max_files
  24. ceph_vxattrcb_snap_btime_exists
  25. ceph_vxattrcb_snap_btime
  26. ceph_inode_vxattrs
  27. ceph_match_vxattr
  28. __set_xattr
  29. __get_xattr
  30. __free_xattr
  31. __remove_xattr
  32. __copy_xattr_names
  33. __ceph_destroy_xattrs
  34. __build_xattrs
  35. __get_required_blob_size
  36. __ceph_build_xattrs_blob
  37. __get_request_mask
  38. __ceph_getxattr
  39. ceph_listxattr
  40. ceph_sync_setxattr
  41. __ceph_setxattr
  42. ceph_get_xattr_handler
  43. ceph_set_xattr_handler
  44. ceph_security_xattr_wanted
  45. ceph_security_xattr_deadlock
  46. ceph_security_init_secctx
  47. ceph_release_acl_sec_ctx

   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         int 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 ver=%lld index_ver=%lld\n", inode,
 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 issued %s\n", inode, ceph_cap_string(issued));
1082         __build_xattrs(inode);
1083 
1084         required_blob_size = __get_required_blob_size(ci, name_len, val_len);
1085 
1086         if (!ci->i_xattrs.prealloc_blob ||
1087             required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
1088                 struct ceph_buffer *blob;
1089 
1090                 spin_unlock(&ci->i_ceph_lock);
1091                 ceph_buffer_put(old_blob); /* Shouldn't be required */
1092                 dout(" pre-allocating new blob size=%d\n", required_blob_size);
1093                 blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
1094                 if (!blob)
1095                         goto do_sync_unlocked;
1096                 spin_lock(&ci->i_ceph_lock);
1097                 /* prealloc_blob can't be released while holding i_ceph_lock */
1098                 if (ci->i_xattrs.prealloc_blob)
1099                         old_blob = ci->i_xattrs.prealloc_blob;
1100                 ci->i_xattrs.prealloc_blob = blob;
1101                 goto retry;
1102         }
1103 
1104         err = __set_xattr(ci, newname, name_len, newval, val_len,
1105                           flags, value ? 1 : -1, &xattr);
1106 
1107         if (!err) {
1108                 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL,
1109                                                &prealloc_cf);
1110                 ci->i_xattrs.dirty = true;
1111                 inode->i_ctime = current_time(inode);
1112         }
1113 
1114         spin_unlock(&ci->i_ceph_lock);
1115         ceph_buffer_put(old_blob);
1116         if (lock_snap_rwsem)
1117                 up_read(&mdsc->snap_rwsem);
1118         if (dirty)
1119                 __mark_inode_dirty(inode, dirty);
1120         ceph_free_cap_flush(prealloc_cf);
1121         return err;
1122 
1123 do_sync:
1124         spin_unlock(&ci->i_ceph_lock);
1125 do_sync_unlocked:
1126         if (lock_snap_rwsem)
1127                 up_read(&mdsc->snap_rwsem);
1128 
1129         /* security module set xattr while filling trace */
1130         if (current->journal_info) {
1131                 pr_warn_ratelimited("sync setxattr %p "
1132                                     "during filling trace\n", inode);
1133                 err = -EBUSY;
1134         } else {
1135                 err = ceph_sync_setxattr(inode, name, value, size, flags);
1136                 if (err >= 0 && check_realm) {
1137                         /* check if snaprealm was created for quota inode */
1138                         spin_lock(&ci->i_ceph_lock);
1139                         if ((ci->i_max_files || ci->i_max_bytes) &&
1140                             !(ci->i_snap_realm &&
1141                               ci->i_snap_realm->ino == ci->i_vino.ino))
1142                                 err = -EOPNOTSUPP;
1143                         spin_unlock(&ci->i_ceph_lock);
1144                 }
1145         }
1146 out:
1147         ceph_free_cap_flush(prealloc_cf);
1148         kfree(newname);
1149         kfree(newval);
1150         kfree(xattr);
1151         return err;
1152 }
1153 
1154 static int ceph_get_xattr_handler(const struct xattr_handler *handler,
1155                                   struct dentry *dentry, struct inode *inode,
1156                                   const char *name, void *value, size_t size)
1157 {
1158         if (!ceph_is_valid_xattr(name))
1159                 return -EOPNOTSUPP;
1160         return __ceph_getxattr(inode, name, value, size);
1161 }
1162 
1163 static int ceph_set_xattr_handler(const struct xattr_handler *handler,
1164                                   struct dentry *unused, struct inode *inode,
1165                                   const char *name, const void *value,
1166                                   size_t size, int flags)
1167 {
1168         if (!ceph_is_valid_xattr(name))
1169                 return -EOPNOTSUPP;
1170         return __ceph_setxattr(inode, name, value, size, flags);
1171 }
1172 
1173 static const struct xattr_handler ceph_other_xattr_handler = {
1174         .prefix = "",  /* match any name => handlers called with full name */
1175         .get = ceph_get_xattr_handler,
1176         .set = ceph_set_xattr_handler,
1177 };
1178 
1179 #ifdef CONFIG_SECURITY
1180 bool ceph_security_xattr_wanted(struct inode *in)
1181 {
1182         return in->i_security != NULL;
1183 }
1184 
1185 bool ceph_security_xattr_deadlock(struct inode *in)
1186 {
1187         struct ceph_inode_info *ci;
1188         bool ret;
1189         if (!in->i_security)
1190                 return false;
1191         ci = ceph_inode(in);
1192         spin_lock(&ci->i_ceph_lock);
1193         ret = !(ci->i_ceph_flags & CEPH_I_SEC_INITED) &&
1194               !(ci->i_xattrs.version > 0 &&
1195                 __ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 0));
1196         spin_unlock(&ci->i_ceph_lock);
1197         return ret;
1198 }
1199 
1200 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1201 int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
1202                            struct ceph_acl_sec_ctx *as_ctx)
1203 {
1204         struct ceph_pagelist *pagelist = as_ctx->pagelist;
1205         const char *name;
1206         size_t name_len;
1207         int err;
1208 
1209         err = security_dentry_init_security(dentry, mode, &dentry->d_name,
1210                                             &as_ctx->sec_ctx,
1211                                             &as_ctx->sec_ctxlen);
1212         if (err < 0) {
1213                 WARN_ON_ONCE(err != -EOPNOTSUPP);
1214                 err = 0; /* do nothing */
1215                 goto out;
1216         }
1217 
1218         err = -ENOMEM;
1219         if (!pagelist) {
1220                 pagelist = ceph_pagelist_alloc(GFP_KERNEL);
1221                 if (!pagelist)
1222                         goto out;
1223                 err = ceph_pagelist_reserve(pagelist, PAGE_SIZE);
1224                 if (err)
1225                         goto out;
1226                 ceph_pagelist_encode_32(pagelist, 1);
1227         }
1228 
1229         /*
1230          * FIXME: Make security_dentry_init_security() generic. Currently
1231          * It only supports single security module and only selinux has
1232          * dentry_init_security hook.
1233          */
1234         name = XATTR_NAME_SELINUX;
1235         name_len = strlen(name);
1236         err = ceph_pagelist_reserve(pagelist,
1237                                     4 * 2 + name_len + as_ctx->sec_ctxlen);
1238         if (err)
1239                 goto out;
1240 
1241         if (as_ctx->pagelist) {
1242                 /* update count of KV pairs */
1243                 BUG_ON(pagelist->length <= sizeof(__le32));
1244                 if (list_is_singular(&pagelist->head)) {
1245                         le32_add_cpu((__le32*)pagelist->mapped_tail, 1);
1246                 } else {
1247                         struct page *page = list_first_entry(&pagelist->head,
1248                                                              struct page, lru);
1249                         void *addr = kmap_atomic(page);
1250                         le32_add_cpu((__le32*)addr, 1);
1251                         kunmap_atomic(addr);
1252                 }
1253         } else {
1254                 as_ctx->pagelist = pagelist;
1255         }
1256 
1257         ceph_pagelist_encode_32(pagelist, name_len);
1258         ceph_pagelist_append(pagelist, name, name_len);
1259 
1260         ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen);
1261         ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1262 
1263         err = 0;
1264 out:
1265         if (pagelist && !as_ctx->pagelist)
1266                 ceph_pagelist_release(pagelist);
1267         return err;
1268 }
1269 #endif /* CONFIG_CEPH_FS_SECURITY_LABEL */
1270 #endif /* CONFIG_SECURITY */
1271 
1272 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
1273 {
1274 #ifdef CONFIG_CEPH_FS_POSIX_ACL
1275         posix_acl_release(as_ctx->acl);
1276         posix_acl_release(as_ctx->default_acl);
1277 #endif
1278 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1279         security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1280 #endif
1281         if (as_ctx->pagelist)
1282                 ceph_pagelist_release(as_ctx->pagelist);
1283 }
1284 
1285 /*
1286  * List of handlers for synthetic system.* attributes. Other
1287  * attributes are handled directly.
1288  */
1289 const struct xattr_handler *ceph_xattr_handlers[] = {
1290 #ifdef CONFIG_CEPH_FS_POSIX_ACL
1291         &posix_acl_access_xattr_handler,
1292         &posix_acl_default_xattr_handler,
1293 #endif
1294         &ceph_other_xattr_handler,
1295         NULL,
1296 };

/* [<][>][^][v][top][bottom][index][help] */