diff options
| author | Ilya Dryomov <idryomov@gmail.com> | 2016-04-29 13:54:20 -0400 |
|---|---|---|
| committer | Ilya Dryomov <idryomov@gmail.com> | 2016-05-25 18:36:22 -0400 |
| commit | d30291b985d1854565d7f2c82a4457869d5265e8 (patch) | |
| tree | 43b99c978c5e4ea321d72590dfeebd42c10de28e /include/linux/ceph | |
| parent | 711da55d36a6f1eddcd340969be7223110d2f6b0 (diff) | |
libceph: variable-sized ceph_object_id
Currently ceph_object_id can hold object names of up to 100
(CEPH_MAX_OID_NAME_LEN) characters. This is enough for all use cases,
expect one - long rbd image names:
- a format 1 header is named "<imgname>.rbd"
- an object that points to a format 2 header is named "rbd_id.<imgname>"
We operate on these potentially long-named objects during rbd map, and,
for format 1 images, during header refresh. (A format 2 header name is
a small system-generated string.)
Lift this 100 character limit by making ceph_object_id be able to point
to an externally-allocated string. Apart from being able to work with
almost arbitrarily-long named objects, this allows us to reduce the
size of ceph_object_id from >100 bytes to 64 bytes.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'include/linux/ceph')
| -rw-r--r-- | include/linux/ceph/osdmap.h | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h index e55c08bc3a96..777a29412706 100644 --- a/include/linux/ceph/osdmap.h +++ b/include/linux/ceph/osdmap.h | |||
| @@ -64,11 +64,47 @@ struct ceph_object_locator { | |||
| 64 | */ | 64 | */ |
| 65 | #define CEPH_MAX_OID_NAME_LEN 100 | 65 | #define CEPH_MAX_OID_NAME_LEN 100 |
| 66 | 66 | ||
| 67 | /* | ||
| 68 | * 51-char inline_name is long enough for all cephfs and all but one | ||
| 69 | * rbd requests: <imgname> in "<imgname>.rbd"/"rbd_id.<imgname>" can be | ||
| 70 | * arbitrarily long (~PAGE_SIZE). It's done once during rbd map; all | ||
| 71 | * other rbd requests fit into inline_name. | ||
| 72 | * | ||
| 73 | * Makes ceph_object_id 64 bytes on 64-bit. | ||
| 74 | */ | ||
| 75 | #define CEPH_OID_INLINE_LEN 52 | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Both inline and external buffers have space for a NUL-terminator, | ||
| 79 | * which is carried around. It's not required though - RADOS object | ||
| 80 | * names don't have to be NUL-terminated and may contain NULs. | ||
| 81 | */ | ||
| 67 | struct ceph_object_id { | 82 | struct ceph_object_id { |
| 68 | char name[CEPH_MAX_OID_NAME_LEN]; | 83 | char *name; |
| 84 | char inline_name[CEPH_OID_INLINE_LEN]; | ||
| 69 | int name_len; | 85 | int name_len; |
| 70 | }; | 86 | }; |
| 71 | 87 | ||
| 88 | static inline void ceph_oid_init(struct ceph_object_id *oid) | ||
| 89 | { | ||
| 90 | oid->name = oid->inline_name; | ||
| 91 | oid->name_len = 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline bool ceph_oid_empty(const struct ceph_object_id *oid) | ||
| 95 | { | ||
| 96 | return oid->name == oid->inline_name && !oid->name_len; | ||
| 97 | } | ||
| 98 | |||
| 99 | void ceph_oid_copy(struct ceph_object_id *dest, | ||
| 100 | const struct ceph_object_id *src); | ||
| 101 | __printf(2, 3) | ||
| 102 | void ceph_oid_printf(struct ceph_object_id *oid, const char *fmt, ...); | ||
| 103 | __printf(3, 4) | ||
| 104 | int ceph_oid_aprintf(struct ceph_object_id *oid, gfp_t gfp, | ||
| 105 | const char *fmt, ...); | ||
| 106 | void ceph_oid_destroy(struct ceph_object_id *oid); | ||
| 107 | |||
| 72 | struct ceph_pg_mapping { | 108 | struct ceph_pg_mapping { |
| 73 | struct rb_node node; | 109 | struct rb_node node; |
| 74 | struct ceph_pg pgid; | 110 | struct ceph_pg pgid; |
| @@ -113,30 +149,6 @@ struct ceph_osdmap { | |||
| 113 | int crush_scratch_ary[CEPH_PG_MAX_SIZE * 3]; | 149 | int crush_scratch_ary[CEPH_PG_MAX_SIZE * 3]; |
| 114 | }; | 150 | }; |
| 115 | 151 | ||
| 116 | static inline void ceph_oid_set_name(struct ceph_object_id *oid, | ||
| 117 | const char *name) | ||
| 118 | { | ||
| 119 | int len; | ||
| 120 | |||
| 121 | len = strlen(name); | ||
| 122 | if (len > sizeof(oid->name)) { | ||
| 123 | WARN(1, "ceph_oid_set_name '%s' len %d vs %zu, truncating\n", | ||
| 124 | name, len, sizeof(oid->name)); | ||
| 125 | len = sizeof(oid->name); | ||
| 126 | } | ||
| 127 | |||
| 128 | memcpy(oid->name, name, len); | ||
| 129 | oid->name_len = len; | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline void ceph_oid_copy(struct ceph_object_id *dest, | ||
| 133 | struct ceph_object_id *src) | ||
| 134 | { | ||
| 135 | BUG_ON(src->name_len > sizeof(dest->name)); | ||
| 136 | memcpy(dest->name, src->name, src->name_len); | ||
| 137 | dest->name_len = src->name_len; | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline int ceph_osd_exists(struct ceph_osdmap *map, int osd) | 152 | static inline int ceph_osd_exists(struct ceph_osdmap *map, int osd) |
| 141 | { | 153 | { |
| 142 | return osd >= 0 && osd < map->max_osd && | 154 | return osd >= 0 && osd < map->max_osd && |
