aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/xattr.c
diff options
context:
space:
mode:
authorAlex Elder <elder@dreamhost.com>2012-01-23 16:49:28 -0500
committerAlex Elder <elder@dreamhost.com>2012-03-22 11:47:46 -0400
commit3ce6cd1233046eb97d6d2bd5d80c1cd40528ea2f (patch)
tree43025c030db1741222b96156931b6aa2c8b85e51 /fs/ceph/xattr.c
parentaa4066ed7ba60421423c35f66b789bb3dd21d89e (diff)
ceph: avoid repeatedly computing the size of constant vxattr names
All names defined in the directory and file virtual extended attribute tables are constant, and the size of each is known at compile time. So there's no need to compute their length every time any file's attribute is listed. Record the length of each string and use it when needed to determine the space need to represent them. In addition, compute the aggregate size of strings in each table just once at initialization time. Signed-off-by: Alex Elder <elder@dreamhost.com> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/xattr.c')
-rw-r--r--fs/ceph/xattr.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 46be30d6d127..88eaedf78fa9 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -26,6 +26,7 @@ static bool ceph_is_valid_xattr(const char *name)
26 */ 26 */
27struct ceph_vxattr { 27struct ceph_vxattr {
28 char *name; 28 char *name;
29 size_t name_size; /* strlen(name) + 1 (for '\0') */
29 size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, 30 size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
30 size_t size); 31 size_t size);
31 bool readonly; 32 bool readonly;
@@ -87,6 +88,7 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
87#define XATTR_NAME_CEPH(_type, _name) \ 88#define XATTR_NAME_CEPH(_type, _name) \
88 { \ 89 { \
89 .name = CEPH_XATTR_NAME(_type, _name), \ 90 .name = CEPH_XATTR_NAME(_type, _name), \
91 .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
90 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \ 92 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
91 .readonly = true, \ 93 .readonly = true, \
92 } 94 }
@@ -102,6 +104,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
102 XATTR_NAME_CEPH(dir, rctime), 104 XATTR_NAME_CEPH(dir, rctime),
103 { 0 } /* Required table terminator */ 105 { 0 } /* Required table terminator */
104}; 106};
107static size_t ceph_dir_vxattrs_name_size; /* total size of all names */
105 108
106/* files */ 109/* files */
107 110
@@ -127,11 +130,13 @@ static struct ceph_vxattr ceph_file_vxattrs[] = {
127 /* The following extended attribute name is deprecated */ 130 /* The following extended attribute name is deprecated */
128 { 131 {
129 .name = XATTR_CEPH_PREFIX "layout", 132 .name = XATTR_CEPH_PREFIX "layout",
133 .name_size = sizeof (XATTR_CEPH_PREFIX "layout"),
130 .getxattr_cb = ceph_vxattrcb_file_layout, 134 .getxattr_cb = ceph_vxattrcb_file_layout,
131 .readonly = true, 135 .readonly = true,
132 }, 136 },
133 { 0 } /* Required table terminator */ 137 { 0 } /* Required table terminator */
134}; 138};
139static size_t ceph_file_vxattrs_name_size; /* total size of all names */
135 140
136static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode) 141static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
137{ 142{
@@ -142,6 +147,46 @@ static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
142 return NULL; 147 return NULL;
143} 148}
144 149
150static size_t ceph_vxattrs_name_size(struct ceph_vxattr *vxattrs)
151{
152 if (vxattrs == ceph_dir_vxattrs)
153 return ceph_dir_vxattrs_name_size;
154 if (vxattrs == ceph_file_vxattrs)
155 return ceph_file_vxattrs_name_size;
156 BUG();
157
158 return 0;
159}
160
161/*
162 * Compute the aggregate size (including terminating '\0') of all
163 * virtual extended attribute names in the given vxattr table.
164 */
165static size_t __init vxattrs_name_size(struct ceph_vxattr *vxattrs)
166{
167 struct ceph_vxattr *vxattr;
168 size_t size = 0;
169
170 for (vxattr = vxattrs; vxattr->name; vxattr++)
171 size += vxattr->name_size;
172
173 return size;
174}
175
176/* Routines called at initialization and exit time */
177
178void __init ceph_xattr_init(void)
179{
180 ceph_dir_vxattrs_name_size = vxattrs_name_size(ceph_dir_vxattrs);
181 ceph_file_vxattrs_name_size = vxattrs_name_size(ceph_file_vxattrs);
182}
183
184void ceph_xattr_exit(void)
185{
186 ceph_dir_vxattrs_name_size = 0;
187 ceph_file_vxattrs_name_size = 0;
188}
189
145static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode, 190static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
146 const char *name) 191 const char *name)
147{ 192{
@@ -615,11 +660,12 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
615 goto out; 660 goto out;
616 661
617list_xattr: 662list_xattr:
618 vir_namelen = 0; 663 /*
619 /* include virtual dir xattrs */ 664 * Start with virtual dir xattr names (if any) (including
620 if (vxattrs) 665 * terminating '\0' characters for each).
621 for (i = 0; vxattrs[i].name; i++) 666 */
622 vir_namelen += strlen(vxattrs[i].name) + 1; 667 vir_namelen = ceph_vxattrs_name_size(vxattrs);
668
623 /* adding 1 byte per each variable due to the null termination */ 669 /* adding 1 byte per each variable due to the null termination */
624 namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; 670 namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
625 err = -ERANGE; 671 err = -ERANGE;