1 #include <linux/ceph/ceph_debug.h>
4 #include "mds_client.h"
6 #include <linux/ceph/decode.h>
8 #include <linux/xattr.h>
9 #include <linux/slab.h>
11 #define XATTR_CEPH_PREFIX "ceph."
12 #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1)
15 * List of handlers for synthetic system.* attributes. Other
16 * attributes are handled directly.
18 const struct xattr_handler
*ceph_xattr_handlers
[] = {
19 #ifdef CONFIG_CEPH_FS_POSIX_ACL
20 &ceph_xattr_acl_access_handler
,
21 &ceph_xattr_acl_default_handler
,
26 static bool ceph_is_valid_xattr(const char *name
)
28 return !strncmp(name
, XATTR_CEPH_PREFIX
, XATTR_CEPH_PREFIX_LEN
) ||
29 !strncmp(name
, XATTR_SECURITY_PREFIX
,
30 XATTR_SECURITY_PREFIX_LEN
) ||
31 !strncmp(name
, XATTR_SYSTEM_PREFIX
, XATTR_SYSTEM_PREFIX_LEN
) ||
32 !strncmp(name
, XATTR_TRUSTED_PREFIX
, XATTR_TRUSTED_PREFIX_LEN
) ||
33 !strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
);
37 * These define virtual xattrs exposing the recursive directory
38 * statistics and layout metadata.
42 size_t name_size
; /* strlen(name) + 1 (for '\0') */
43 size_t (*getxattr_cb
)(struct ceph_inode_info
*ci
, char *val
,
45 bool readonly
, hidden
;
46 bool (*exists_cb
)(struct ceph_inode_info
*ci
);
51 static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info
*ci
)
54 char *p
= (char *)&ci
->i_layout
;
56 for (s
= 0; s
< sizeof(ci
->i_layout
); s
++, p
++)
62 static size_t ceph_vxattrcb_layout(struct ceph_inode_info
*ci
, char *val
,
66 struct ceph_fs_client
*fsc
= ceph_sb_to_client(ci
->vfs_inode
.i_sb
);
67 struct ceph_osd_client
*osdc
= &fsc
->client
->osdc
;
68 s64 pool
= ceph_file_layout_pg_pool(ci
->i_layout
);
69 const char *pool_name
;
71 dout("ceph_vxattrcb_layout %p\n", &ci
->vfs_inode
);
72 down_read(&osdc
->map_sem
);
73 pool_name
= ceph_pg_pool_name_by_id(osdc
->osdmap
, pool
);
75 ret
= snprintf(val
, size
,
76 "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%s",
77 (unsigned long long)ceph_file_layout_su(ci
->i_layout
),
78 (unsigned long long)ceph_file_layout_stripe_count(ci
->i_layout
),
79 (unsigned long long)ceph_file_layout_object_size(ci
->i_layout
),
82 ret
= snprintf(val
, size
,
83 "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld",
84 (unsigned long long)ceph_file_layout_su(ci
->i_layout
),
85 (unsigned long long)ceph_file_layout_stripe_count(ci
->i_layout
),
86 (unsigned long long)ceph_file_layout_object_size(ci
->i_layout
),
87 (unsigned long long)pool
);
89 up_read(&osdc
->map_sem
);
93 static size_t ceph_vxattrcb_layout_stripe_unit(struct ceph_inode_info
*ci
,
94 char *val
, size_t size
)
96 return snprintf(val
, size
, "%lld",
97 (unsigned long long)ceph_file_layout_su(ci
->i_layout
));
100 static size_t ceph_vxattrcb_layout_stripe_count(struct ceph_inode_info
*ci
,
101 char *val
, size_t size
)
103 return snprintf(val
, size
, "%lld",
104 (unsigned long long)ceph_file_layout_stripe_count(ci
->i_layout
));
107 static size_t ceph_vxattrcb_layout_object_size(struct ceph_inode_info
*ci
,
108 char *val
, size_t size
)
110 return snprintf(val
, size
, "%lld",
111 (unsigned long long)ceph_file_layout_object_size(ci
->i_layout
));
114 static size_t ceph_vxattrcb_layout_pool(struct ceph_inode_info
*ci
,
115 char *val
, size_t size
)
118 struct ceph_fs_client
*fsc
= ceph_sb_to_client(ci
->vfs_inode
.i_sb
);
119 struct ceph_osd_client
*osdc
= &fsc
->client
->osdc
;
120 s64 pool
= ceph_file_layout_pg_pool(ci
->i_layout
);
121 const char *pool_name
;
123 down_read(&osdc
->map_sem
);
124 pool_name
= ceph_pg_pool_name_by_id(osdc
->osdmap
, pool
);
126 ret
= snprintf(val
, size
, "%s", pool_name
);
128 ret
= snprintf(val
, size
, "%lld", (unsigned long long)pool
);
129 up_read(&osdc
->map_sem
);
135 static size_t ceph_vxattrcb_dir_entries(struct ceph_inode_info
*ci
, char *val
,
138 return snprintf(val
, size
, "%lld", ci
->i_files
+ ci
->i_subdirs
);
141 static size_t ceph_vxattrcb_dir_files(struct ceph_inode_info
*ci
, char *val
,
144 return snprintf(val
, size
, "%lld", ci
->i_files
);
147 static size_t ceph_vxattrcb_dir_subdirs(struct ceph_inode_info
*ci
, char *val
,
150 return snprintf(val
, size
, "%lld", ci
->i_subdirs
);
153 static size_t ceph_vxattrcb_dir_rentries(struct ceph_inode_info
*ci
, char *val
,
156 return snprintf(val
, size
, "%lld", ci
->i_rfiles
+ ci
->i_rsubdirs
);
159 static size_t ceph_vxattrcb_dir_rfiles(struct ceph_inode_info
*ci
, char *val
,
162 return snprintf(val
, size
, "%lld", ci
->i_rfiles
);
165 static size_t ceph_vxattrcb_dir_rsubdirs(struct ceph_inode_info
*ci
, char *val
,
168 return snprintf(val
, size
, "%lld", ci
->i_rsubdirs
);
171 static size_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info
*ci
, char *val
,
174 return snprintf(val
, size
, "%lld", ci
->i_rbytes
);
177 static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info
*ci
, char *val
,
180 return snprintf(val
, size
, "%ld.09%ld", (long)ci
->i_rctime
.tv_sec
,
181 (long)ci
->i_rctime
.tv_nsec
);
185 #define CEPH_XATTR_NAME(_type, _name) XATTR_CEPH_PREFIX #_type "." #_name
186 #define CEPH_XATTR_NAME2(_type, _name, _name2) \
187 XATTR_CEPH_PREFIX #_type "." #_name "." #_name2
189 #define XATTR_NAME_CEPH(_type, _name) \
191 .name = CEPH_XATTR_NAME(_type, _name), \
192 .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
193 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
198 #define XATTR_LAYOUT_FIELD(_type, _name, _field) \
200 .name = CEPH_XATTR_NAME2(_type, _name, _field), \
201 .name_size = sizeof (CEPH_XATTR_NAME2(_type, _name, _field)), \
202 .getxattr_cb = ceph_vxattrcb_ ## _name ## _ ## _field, \
205 .exists_cb = ceph_vxattrcb_layout_exists, \
208 static struct ceph_vxattr ceph_dir_vxattrs
[] = {
210 .name
= "ceph.dir.layout",
211 .name_size
= sizeof("ceph.dir.layout"),
212 .getxattr_cb
= ceph_vxattrcb_layout
,
215 .exists_cb
= ceph_vxattrcb_layout_exists
,
217 XATTR_LAYOUT_FIELD(dir
, layout
, stripe_unit
),
218 XATTR_LAYOUT_FIELD(dir
, layout
, stripe_count
),
219 XATTR_LAYOUT_FIELD(dir
, layout
, object_size
),
220 XATTR_LAYOUT_FIELD(dir
, layout
, pool
),
221 XATTR_NAME_CEPH(dir
, entries
),
222 XATTR_NAME_CEPH(dir
, files
),
223 XATTR_NAME_CEPH(dir
, subdirs
),
224 XATTR_NAME_CEPH(dir
, rentries
),
225 XATTR_NAME_CEPH(dir
, rfiles
),
226 XATTR_NAME_CEPH(dir
, rsubdirs
),
227 XATTR_NAME_CEPH(dir
, rbytes
),
228 XATTR_NAME_CEPH(dir
, rctime
),
229 { .name
= NULL
, 0 } /* Required table terminator */
231 static size_t ceph_dir_vxattrs_name_size
; /* total size of all names */
235 static struct ceph_vxattr ceph_file_vxattrs
[] = {
237 .name
= "ceph.file.layout",
238 .name_size
= sizeof("ceph.file.layout"),
239 .getxattr_cb
= ceph_vxattrcb_layout
,
242 .exists_cb
= ceph_vxattrcb_layout_exists
,
244 XATTR_LAYOUT_FIELD(file
, layout
, stripe_unit
),
245 XATTR_LAYOUT_FIELD(file
, layout
, stripe_count
),
246 XATTR_LAYOUT_FIELD(file
, layout
, object_size
),
247 XATTR_LAYOUT_FIELD(file
, layout
, pool
),
248 { .name
= NULL
, 0 } /* Required table terminator */
250 static size_t ceph_file_vxattrs_name_size
; /* total size of all names */
252 static struct ceph_vxattr
*ceph_inode_vxattrs(struct inode
*inode
)
254 if (S_ISDIR(inode
->i_mode
))
255 return ceph_dir_vxattrs
;
256 else if (S_ISREG(inode
->i_mode
))
257 return ceph_file_vxattrs
;
261 static size_t ceph_vxattrs_name_size(struct ceph_vxattr
*vxattrs
)
263 if (vxattrs
== ceph_dir_vxattrs
)
264 return ceph_dir_vxattrs_name_size
;
265 if (vxattrs
== ceph_file_vxattrs
)
266 return ceph_file_vxattrs_name_size
;
273 * Compute the aggregate size (including terminating '\0') of all
274 * virtual extended attribute names in the given vxattr table.
276 static size_t __init
vxattrs_name_size(struct ceph_vxattr
*vxattrs
)
278 struct ceph_vxattr
*vxattr
;
281 for (vxattr
= vxattrs
; vxattr
->name
; vxattr
++)
283 size
+= vxattr
->name_size
;
288 /* Routines called at initialization and exit time */
290 void __init
ceph_xattr_init(void)
292 ceph_dir_vxattrs_name_size
= vxattrs_name_size(ceph_dir_vxattrs
);
293 ceph_file_vxattrs_name_size
= vxattrs_name_size(ceph_file_vxattrs
);
296 void ceph_xattr_exit(void)
298 ceph_dir_vxattrs_name_size
= 0;
299 ceph_file_vxattrs_name_size
= 0;
302 static struct ceph_vxattr
*ceph_match_vxattr(struct inode
*inode
,
305 struct ceph_vxattr
*vxattr
= ceph_inode_vxattrs(inode
);
308 while (vxattr
->name
) {
309 if (!strcmp(vxattr
->name
, name
))
318 static int __set_xattr(struct ceph_inode_info
*ci
,
319 const char *name
, int name_len
,
320 const char *val
, int val_len
,
322 int should_free_name
, int should_free_val
,
323 struct ceph_inode_xattr
**newxattr
)
326 struct rb_node
*parent
= NULL
;
327 struct ceph_inode_xattr
*xattr
= NULL
;
331 p
= &ci
->i_xattrs
.index
.rb_node
;
334 xattr
= rb_entry(parent
, struct ceph_inode_xattr
, node
);
335 c
= strncmp(name
, xattr
->name
, min(name_len
, xattr
->name_len
));
341 if (name_len
== xattr
->name_len
)
343 else if (name_len
< xattr
->name_len
)
355 xattr
->name_len
= name_len
;
356 xattr
->should_free_name
= should_free_name
;
358 ci
->i_xattrs
.count
++;
359 dout("__set_xattr count=%d\n", ci
->i_xattrs
.count
);
363 if (xattr
->should_free_val
)
364 kfree((void *)xattr
->val
);
366 if (should_free_name
) {
370 ci
->i_xattrs
.names_size
-= xattr
->name_len
;
371 ci
->i_xattrs
.vals_size
-= xattr
->val_len
;
373 ci
->i_xattrs
.names_size
+= name_len
;
374 ci
->i_xattrs
.vals_size
+= val_len
;
380 xattr
->val_len
= val_len
;
381 xattr
->dirty
= dirty
;
382 xattr
->should_free_val
= (val
&& should_free_val
);
385 rb_link_node(&xattr
->node
, parent
, p
);
386 rb_insert_color(&xattr
->node
, &ci
->i_xattrs
.index
);
387 dout("__set_xattr_val p=%p\n", p
);
390 dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n",
391 ceph_vinop(&ci
->vfs_inode
), xattr
, name
, val_len
, val
);
396 static struct ceph_inode_xattr
*__get_xattr(struct ceph_inode_info
*ci
,
400 struct rb_node
*parent
= NULL
;
401 struct ceph_inode_xattr
*xattr
= NULL
;
402 int name_len
= strlen(name
);
405 p
= &ci
->i_xattrs
.index
.rb_node
;
408 xattr
= rb_entry(parent
, struct ceph_inode_xattr
, node
);
409 c
= strncmp(name
, xattr
->name
, xattr
->name_len
);
410 if (c
== 0 && name_len
> xattr
->name_len
)
417 dout("__get_xattr %s: found %.*s\n", name
,
418 xattr
->val_len
, xattr
->val
);
423 dout("__get_xattr %s: not found\n", name
);
428 static void __free_xattr(struct ceph_inode_xattr
*xattr
)
432 if (xattr
->should_free_name
)
433 kfree((void *)xattr
->name
);
434 if (xattr
->should_free_val
)
435 kfree((void *)xattr
->val
);
440 static int __remove_xattr(struct ceph_inode_info
*ci
,
441 struct ceph_inode_xattr
*xattr
)
446 rb_erase(&xattr
->node
, &ci
->i_xattrs
.index
);
448 if (xattr
->should_free_name
)
449 kfree((void *)xattr
->name
);
450 if (xattr
->should_free_val
)
451 kfree((void *)xattr
->val
);
453 ci
->i_xattrs
.names_size
-= xattr
->name_len
;
454 ci
->i_xattrs
.vals_size
-= xattr
->val_len
;
455 ci
->i_xattrs
.count
--;
461 static int __remove_xattr_by_name(struct ceph_inode_info
*ci
,
465 struct ceph_inode_xattr
*xattr
;
468 p
= &ci
->i_xattrs
.index
.rb_node
;
469 xattr
= __get_xattr(ci
, name
);
470 err
= __remove_xattr(ci
, xattr
);
474 static char *__copy_xattr_names(struct ceph_inode_info
*ci
,
478 struct ceph_inode_xattr
*xattr
= NULL
;
480 p
= rb_first(&ci
->i_xattrs
.index
);
481 dout("__copy_xattr_names count=%d\n", ci
->i_xattrs
.count
);
484 xattr
= rb_entry(p
, struct ceph_inode_xattr
, node
);
485 memcpy(dest
, xattr
->name
, xattr
->name_len
);
486 dest
[xattr
->name_len
] = '\0';
488 dout("dest=%s %p (%s) (%d/%d)\n", dest
, xattr
, xattr
->name
,
489 xattr
->name_len
, ci
->i_xattrs
.names_size
);
491 dest
+= xattr
->name_len
+ 1;
498 void __ceph_destroy_xattrs(struct ceph_inode_info
*ci
)
500 struct rb_node
*p
, *tmp
;
501 struct ceph_inode_xattr
*xattr
= NULL
;
503 p
= rb_first(&ci
->i_xattrs
.index
);
505 dout("__ceph_destroy_xattrs p=%p\n", p
);
508 xattr
= rb_entry(p
, struct ceph_inode_xattr
, node
);
511 dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p
,
512 xattr
->name_len
, xattr
->name
);
513 rb_erase(tmp
, &ci
->i_xattrs
.index
);
518 ci
->i_xattrs
.names_size
= 0;
519 ci
->i_xattrs
.vals_size
= 0;
520 ci
->i_xattrs
.index_version
= 0;
521 ci
->i_xattrs
.count
= 0;
522 ci
->i_xattrs
.index
= RB_ROOT
;
525 static int __build_xattrs(struct inode
*inode
)
526 __releases(ci
->i_ceph_lock
)
527 __acquires(ci
->i_ceph_lock
)
533 const char *name
, *val
;
534 struct ceph_inode_info
*ci
= ceph_inode(inode
);
536 struct ceph_inode_xattr
**xattrs
= NULL
;
540 dout("__build_xattrs() len=%d\n",
541 ci
->i_xattrs
.blob
? (int)ci
->i_xattrs
.blob
->vec
.iov_len
: 0);
543 if (ci
->i_xattrs
.index_version
>= ci
->i_xattrs
.version
)
544 return 0; /* already built */
546 __ceph_destroy_xattrs(ci
);
549 /* updated internal xattr rb tree */
550 if (ci
->i_xattrs
.blob
&& ci
->i_xattrs
.blob
->vec
.iov_len
> 4) {
551 p
= ci
->i_xattrs
.blob
->vec
.iov_base
;
552 end
= p
+ ci
->i_xattrs
.blob
->vec
.iov_len
;
553 ceph_decode_32_safe(&p
, end
, numattr
, bad
);
554 xattr_version
= ci
->i_xattrs
.version
;
555 spin_unlock(&ci
->i_ceph_lock
);
557 xattrs
= kcalloc(numattr
, sizeof(struct ceph_xattr
*),
562 memset(xattrs
, 0, numattr
*sizeof(struct ceph_xattr
*));
563 for (i
= 0; i
< numattr
; i
++) {
564 xattrs
[i
] = kmalloc(sizeof(struct ceph_inode_xattr
),
570 spin_lock(&ci
->i_ceph_lock
);
571 if (ci
->i_xattrs
.version
!= xattr_version
) {
572 /* lost a race, retry */
573 for (i
= 0; i
< numattr
; i
++)
581 ceph_decode_32_safe(&p
, end
, len
, bad
);
585 ceph_decode_32_safe(&p
, end
, len
, bad
);
589 err
= __set_xattr(ci
, name
, namelen
, val
, len
,
590 0, 0, 0, &xattrs
[numattr
]);
597 ci
->i_xattrs
.index_version
= ci
->i_xattrs
.version
;
598 ci
->i_xattrs
.dirty
= false;
602 spin_lock(&ci
->i_ceph_lock
);
605 for (i
= 0; i
< numattr
; i
++)
609 ci
->i_xattrs
.names_size
= 0;
613 static int __get_required_blob_size(struct ceph_inode_info
*ci
, int name_size
,
617 * 4 bytes for the length, and additional 4 bytes per each xattr name,
618 * 4 bytes per each value
620 int size
= 4 + ci
->i_xattrs
.count
*(4 + 4) +
621 ci
->i_xattrs
.names_size
+
622 ci
->i_xattrs
.vals_size
;
623 dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
624 ci
->i_xattrs
.count
, ci
->i_xattrs
.names_size
,
625 ci
->i_xattrs
.vals_size
);
628 size
+= 4 + 4 + name_size
+ val_size
;
634 * If there are dirty xattrs, reencode xattrs into the prealloc_blob
635 * and swap into place.
637 void __ceph_build_xattrs_blob(struct ceph_inode_info
*ci
)
640 struct ceph_inode_xattr
*xattr
= NULL
;
643 dout("__build_xattrs_blob %p\n", &ci
->vfs_inode
);
644 if (ci
->i_xattrs
.dirty
) {
645 int need
= __get_required_blob_size(ci
, 0, 0);
647 BUG_ON(need
> ci
->i_xattrs
.prealloc_blob
->alloc_len
);
649 p
= rb_first(&ci
->i_xattrs
.index
);
650 dest
= ci
->i_xattrs
.prealloc_blob
->vec
.iov_base
;
652 ceph_encode_32(&dest
, ci
->i_xattrs
.count
);
654 xattr
= rb_entry(p
, struct ceph_inode_xattr
, node
);
656 ceph_encode_32(&dest
, xattr
->name_len
);
657 memcpy(dest
, xattr
->name
, xattr
->name_len
);
658 dest
+= xattr
->name_len
;
659 ceph_encode_32(&dest
, xattr
->val_len
);
660 memcpy(dest
, xattr
->val
, xattr
->val_len
);
661 dest
+= xattr
->val_len
;
666 /* adjust buffer len; it may be larger than we need */
667 ci
->i_xattrs
.prealloc_blob
->vec
.iov_len
=
668 dest
- ci
->i_xattrs
.prealloc_blob
->vec
.iov_base
;
670 if (ci
->i_xattrs
.blob
)
671 ceph_buffer_put(ci
->i_xattrs
.blob
);
672 ci
->i_xattrs
.blob
= ci
->i_xattrs
.prealloc_blob
;
673 ci
->i_xattrs
.prealloc_blob
= NULL
;
674 ci
->i_xattrs
.dirty
= false;
675 ci
->i_xattrs
.version
++;
679 ssize_t
__ceph_getxattr(struct inode
*inode
, const char *name
, void *value
,
682 struct ceph_inode_info
*ci
= ceph_inode(inode
);
684 struct ceph_inode_xattr
*xattr
;
685 struct ceph_vxattr
*vxattr
= NULL
;
687 if (!ceph_is_valid_xattr(name
))
690 /* let's see if a virtual xattr was requested */
691 vxattr
= ceph_match_vxattr(inode
, name
);
692 if (vxattr
&& !(vxattr
->exists_cb
&& !vxattr
->exists_cb(ci
))) {
693 err
= vxattr
->getxattr_cb(ci
, value
, size
);
697 spin_lock(&ci
->i_ceph_lock
);
698 dout("getxattr %p ver=%lld index_ver=%lld\n", inode
,
699 ci
->i_xattrs
.version
, ci
->i_xattrs
.index_version
);
701 if (__ceph_caps_issued_mask(ci
, CEPH_CAP_XATTR_SHARED
, 1) &&
702 (ci
->i_xattrs
.index_version
>= ci
->i_xattrs
.version
)) {
705 spin_unlock(&ci
->i_ceph_lock
);
706 /* get xattrs from mds (if we don't already have them) */
707 err
= ceph_do_getattr(inode
, CEPH_STAT_CAP_XATTR
);
712 spin_lock(&ci
->i_ceph_lock
);
714 err
= __build_xattrs(inode
);
719 err
= -ENODATA
; /* == ENOATTR */
720 xattr
= __get_xattr(ci
, name
);
725 if (size
&& size
< xattr
->val_len
)
728 err
= xattr
->val_len
;
732 memcpy(value
, xattr
->val
, xattr
->val_len
);
735 spin_unlock(&ci
->i_ceph_lock
);
739 ssize_t
ceph_getxattr(struct dentry
*dentry
, const char *name
, void *value
,
742 if (!strncmp(name
, XATTR_SYSTEM_PREFIX
, XATTR_SYSTEM_PREFIX_LEN
))
743 return generic_getxattr(dentry
, name
, value
, size
);
745 return __ceph_getxattr(dentry
->d_inode
, name
, value
, size
);
748 ssize_t
ceph_listxattr(struct dentry
*dentry
, char *names
, size_t size
)
750 struct inode
*inode
= dentry
->d_inode
;
751 struct ceph_inode_info
*ci
= ceph_inode(inode
);
752 struct ceph_vxattr
*vxattrs
= ceph_inode_vxattrs(inode
);
759 spin_lock(&ci
->i_ceph_lock
);
760 dout("listxattr %p ver=%lld index_ver=%lld\n", inode
,
761 ci
->i_xattrs
.version
, ci
->i_xattrs
.index_version
);
763 if (__ceph_caps_issued_mask(ci
, CEPH_CAP_XATTR_SHARED
, 1) &&
764 (ci
->i_xattrs
.index_version
>= ci
->i_xattrs
.version
)) {
767 spin_unlock(&ci
->i_ceph_lock
);
768 err
= ceph_do_getattr(inode
, CEPH_STAT_CAP_XATTR
);
773 spin_lock(&ci
->i_ceph_lock
);
775 err
= __build_xattrs(inode
);
781 * Start with virtual dir xattr names (if any) (including
782 * terminating '\0' characters for each).
784 vir_namelen
= ceph_vxattrs_name_size(vxattrs
);
786 /* adding 1 byte per each variable due to the null termination */
787 namelen
= ci
->i_xattrs
.names_size
+ ci
->i_xattrs
.count
;
789 if (size
&& vir_namelen
+ namelen
> size
)
792 err
= namelen
+ vir_namelen
;
796 names
= __copy_xattr_names(ci
, names
);
798 /* virtual xattr names, too */
801 for (i
= 0; vxattrs
[i
].name
; i
++) {
802 if (!vxattrs
[i
].hidden
&&
803 !(vxattrs
[i
].exists_cb
&&
804 !vxattrs
[i
].exists_cb(ci
))) {
805 len
= sprintf(names
, "%s", vxattrs
[i
].name
);
813 spin_unlock(&ci
->i_ceph_lock
);
817 static int ceph_sync_setxattr(struct dentry
*dentry
, const char *name
,
818 const char *value
, size_t size
, int flags
)
820 struct ceph_fs_client
*fsc
= ceph_sb_to_client(dentry
->d_sb
);
821 struct inode
*inode
= dentry
->d_inode
;
822 struct ceph_inode_info
*ci
= ceph_inode(inode
);
823 struct inode
*parent_inode
;
824 struct ceph_mds_request
*req
;
825 struct ceph_mds_client
*mdsc
= fsc
->mdsc
;
828 struct page
**pages
= NULL
;
831 /* copy value into some pages */
832 nr_pages
= calc_pages_for(0, size
);
834 pages
= kmalloc(sizeof(pages
[0])*nr_pages
, GFP_NOFS
);
838 for (i
= 0; i
< nr_pages
; i
++) {
839 pages
[i
] = __page_cache_alloc(GFP_NOFS
);
844 kaddr
= kmap(pages
[i
]);
845 memcpy(kaddr
, value
+ i
*PAGE_CACHE_SIZE
,
846 min(PAGE_CACHE_SIZE
, size
-i
*PAGE_CACHE_SIZE
));
850 dout("setxattr value=%.*s\n", (int)size
, value
);
853 req
= ceph_mdsc_create_request(mdsc
, CEPH_MDS_OP_SETXATTR
,
859 req
->r_inode
= inode
;
861 req
->r_inode_drop
= CEPH_CAP_XATTR_SHARED
;
863 req
->r_args
.setxattr
.flags
= cpu_to_le32(flags
);
864 req
->r_path2
= kstrdup(name
, GFP_NOFS
);
866 req
->r_pages
= pages
;
867 req
->r_num_pages
= nr_pages
;
868 req
->r_data_len
= size
;
870 dout("xattr.ver (before): %lld\n", ci
->i_xattrs
.version
);
871 parent_inode
= ceph_get_dentry_parent_inode(dentry
);
872 err
= ceph_mdsc_do_request(mdsc
, parent_inode
, req
);
874 ceph_mdsc_put_request(req
);
875 dout("xattr.ver (after): %lld\n", ci
->i_xattrs
.version
);
879 for (i
= 0; i
< nr_pages
; i
++)
880 __free_page(pages
[i
]);
886 int __ceph_setxattr(struct dentry
*dentry
, const char *name
,
887 const void *value
, size_t size
, int flags
)
889 struct inode
*inode
= dentry
->d_inode
;
890 struct ceph_vxattr
*vxattr
;
891 struct ceph_inode_info
*ci
= ceph_inode(inode
);
895 int name_len
= strlen(name
);
897 char *newname
= NULL
;
899 struct ceph_inode_xattr
*xattr
= NULL
;
900 int required_blob_size
;
902 if (!ceph_is_valid_xattr(name
))
905 vxattr
= ceph_match_vxattr(inode
, name
);
906 if (vxattr
&& vxattr
->readonly
)
909 /* pass any unhandled ceph.* xattrs through to the MDS */
910 if (!strncmp(name
, XATTR_CEPH_PREFIX
, XATTR_CEPH_PREFIX_LEN
))
911 goto do_sync_unlocked
;
913 /* preallocate memory for xattr name, value, index node */
915 newname
= kmemdup(name
, name_len
+ 1, GFP_NOFS
);
920 newval
= kmemdup(value
, val_len
, GFP_NOFS
);
925 xattr
= kmalloc(sizeof(struct ceph_inode_xattr
), GFP_NOFS
);
929 spin_lock(&ci
->i_ceph_lock
);
931 issued
= __ceph_caps_issued(ci
, NULL
);
932 dout("setxattr %p issued %s\n", inode
, ceph_cap_string(issued
));
933 if (!(issued
& CEPH_CAP_XATTR_EXCL
))
935 __build_xattrs(inode
);
937 required_blob_size
= __get_required_blob_size(ci
, name_len
, val_len
);
939 if (!ci
->i_xattrs
.prealloc_blob
||
940 required_blob_size
> ci
->i_xattrs
.prealloc_blob
->alloc_len
) {
941 struct ceph_buffer
*blob
;
943 spin_unlock(&ci
->i_ceph_lock
);
944 dout(" preaallocating new blob size=%d\n", required_blob_size
);
945 blob
= ceph_buffer_new(required_blob_size
, GFP_NOFS
);
948 spin_lock(&ci
->i_ceph_lock
);
949 if (ci
->i_xattrs
.prealloc_blob
)
950 ceph_buffer_put(ci
->i_xattrs
.prealloc_blob
);
951 ci
->i_xattrs
.prealloc_blob
= blob
;
955 err
= __set_xattr(ci
, newname
, name_len
, newval
,
956 val_len
, 1, 1, 1, &xattr
);
958 dirty
= __ceph_mark_dirty_caps(ci
, CEPH_CAP_XATTR_EXCL
);
959 ci
->i_xattrs
.dirty
= true;
960 inode
->i_ctime
= CURRENT_TIME
;
962 spin_unlock(&ci
->i_ceph_lock
);
964 __mark_inode_dirty(inode
, dirty
);
968 spin_unlock(&ci
->i_ceph_lock
);
970 err
= ceph_sync_setxattr(dentry
, name
, value
, size
, flags
);
978 int ceph_setxattr(struct dentry
*dentry
, const char *name
,
979 const void *value
, size_t size
, int flags
)
981 if (ceph_snap(dentry
->d_inode
) != CEPH_NOSNAP
)
984 if (!strncmp(name
, XATTR_SYSTEM_PREFIX
, XATTR_SYSTEM_PREFIX_LEN
))
985 return generic_setxattr(dentry
, name
, value
, size
, flags
);
987 return __ceph_setxattr(dentry
, name
, value
, size
, flags
);
990 static int ceph_send_removexattr(struct dentry
*dentry
, const char *name
)
992 struct ceph_fs_client
*fsc
= ceph_sb_to_client(dentry
->d_sb
);
993 struct ceph_mds_client
*mdsc
= fsc
->mdsc
;
994 struct inode
*inode
= dentry
->d_inode
;
995 struct inode
*parent_inode
;
996 struct ceph_mds_request
*req
;
999 req
= ceph_mdsc_create_request(mdsc
, CEPH_MDS_OP_RMXATTR
,
1002 return PTR_ERR(req
);
1003 req
->r_inode
= inode
;
1005 req
->r_inode_drop
= CEPH_CAP_XATTR_SHARED
;
1006 req
->r_num_caps
= 1;
1007 req
->r_path2
= kstrdup(name
, GFP_NOFS
);
1009 parent_inode
= ceph_get_dentry_parent_inode(dentry
);
1010 err
= ceph_mdsc_do_request(mdsc
, parent_inode
, req
);
1012 ceph_mdsc_put_request(req
);
1016 int __ceph_removexattr(struct dentry
*dentry
, const char *name
)
1018 struct inode
*inode
= dentry
->d_inode
;
1019 struct ceph_vxattr
*vxattr
;
1020 struct ceph_inode_info
*ci
= ceph_inode(inode
);
1023 int required_blob_size
;
1026 if (!ceph_is_valid_xattr(name
))
1029 vxattr
= ceph_match_vxattr(inode
, name
);
1030 if (vxattr
&& vxattr
->readonly
)
1033 /* pass any unhandled ceph.* xattrs through to the MDS */
1034 if (!strncmp(name
, XATTR_CEPH_PREFIX
, XATTR_CEPH_PREFIX_LEN
))
1035 goto do_sync_unlocked
;
1038 spin_lock(&ci
->i_ceph_lock
);
1040 issued
= __ceph_caps_issued(ci
, NULL
);
1041 dout("removexattr %p issued %s\n", inode
, ceph_cap_string(issued
));
1043 if (!(issued
& CEPH_CAP_XATTR_EXCL
))
1045 __build_xattrs(inode
);
1047 required_blob_size
= __get_required_blob_size(ci
, 0, 0);
1049 if (!ci
->i_xattrs
.prealloc_blob
||
1050 required_blob_size
> ci
->i_xattrs
.prealloc_blob
->alloc_len
) {
1051 struct ceph_buffer
*blob
;
1053 spin_unlock(&ci
->i_ceph_lock
);
1054 dout(" preaallocating new blob size=%d\n", required_blob_size
);
1055 blob
= ceph_buffer_new(required_blob_size
, GFP_NOFS
);
1058 spin_lock(&ci
->i_ceph_lock
);
1059 if (ci
->i_xattrs
.prealloc_blob
)
1060 ceph_buffer_put(ci
->i_xattrs
.prealloc_blob
);
1061 ci
->i_xattrs
.prealloc_blob
= blob
;
1065 err
= __remove_xattr_by_name(ceph_inode(inode
), name
);
1067 dirty
= __ceph_mark_dirty_caps(ci
, CEPH_CAP_XATTR_EXCL
);
1068 ci
->i_xattrs
.dirty
= true;
1069 inode
->i_ctime
= CURRENT_TIME
;
1070 spin_unlock(&ci
->i_ceph_lock
);
1072 __mark_inode_dirty(inode
, dirty
);
1075 spin_unlock(&ci
->i_ceph_lock
);
1077 err
= ceph_send_removexattr(dentry
, name
);
1082 int ceph_removexattr(struct dentry
*dentry
, const char *name
)
1084 if (ceph_snap(dentry
->d_inode
) != CEPH_NOSNAP
)
1087 if (!strncmp(name
, XATTR_SYSTEM_PREFIX
, XATTR_SYSTEM_PREFIX_LEN
))
1088 return generic_removexattr(dentry
, name
);
1090 return __ceph_removexattr(dentry
, name
);