提交 3ce6cd12 编写于 作者: A Alex Elder

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: NAlex Elder <elder@dreamhost.com>
Signed-off-by: NSage Weil <sage@newdream.net>
上级 aa4066ed
...@@ -927,6 +927,7 @@ static int __init init_ceph(void) ...@@ -927,6 +927,7 @@ static int __init init_ceph(void)
if (ret) if (ret)
goto out; goto out;
ceph_xattr_init();
ret = register_filesystem(&ceph_fs_type); ret = register_filesystem(&ceph_fs_type);
if (ret) if (ret)
goto out_icache; goto out_icache;
...@@ -936,6 +937,7 @@ static int __init init_ceph(void) ...@@ -936,6 +937,7 @@ static int __init init_ceph(void)
return 0; return 0;
out_icache: out_icache:
ceph_xattr_exit();
destroy_caches(); destroy_caches();
out: out:
return ret; return ret;
...@@ -945,6 +947,7 @@ static void __exit exit_ceph(void) ...@@ -945,6 +947,7 @@ static void __exit exit_ceph(void)
{ {
dout("exit_ceph\n"); dout("exit_ceph\n");
unregister_filesystem(&ceph_fs_type); unregister_filesystem(&ceph_fs_type);
ceph_xattr_exit();
destroy_caches(); destroy_caches();
} }
......
...@@ -733,6 +733,8 @@ extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); ...@@ -733,6 +733,8 @@ extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
extern int ceph_removexattr(struct dentry *, const char *); extern int ceph_removexattr(struct dentry *, const char *);
extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci);
extern void __init ceph_xattr_init(void);
extern void ceph_xattr_exit(void);
/* caps.c */ /* caps.c */
extern const char *ceph_cap_string(int c); extern const char *ceph_cap_string(int c);
......
...@@ -26,6 +26,7 @@ static bool ceph_is_valid_xattr(const char *name) ...@@ -26,6 +26,7 @@ static bool ceph_is_valid_xattr(const char *name)
*/ */
struct ceph_vxattr { struct ceph_vxattr {
char *name; char *name;
size_t name_size; /* strlen(name) + 1 (for '\0') */
size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
size_t size); size_t size);
bool readonly; bool readonly;
...@@ -87,6 +88,7 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, ...@@ -87,6 +88,7 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
#define XATTR_NAME_CEPH(_type, _name) \ #define XATTR_NAME_CEPH(_type, _name) \
{ \ { \
.name = CEPH_XATTR_NAME(_type, _name), \ .name = CEPH_XATTR_NAME(_type, _name), \
.name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
.getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \ .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
.readonly = true, \ .readonly = true, \
} }
...@@ -102,6 +104,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = { ...@@ -102,6 +104,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
XATTR_NAME_CEPH(dir, rctime), XATTR_NAME_CEPH(dir, rctime),
{ 0 } /* Required table terminator */ { 0 } /* Required table terminator */
}; };
static size_t ceph_dir_vxattrs_name_size; /* total size of all names */
/* files */ /* files */
...@@ -127,11 +130,13 @@ static struct ceph_vxattr ceph_file_vxattrs[] = { ...@@ -127,11 +130,13 @@ static struct ceph_vxattr ceph_file_vxattrs[] = {
/* The following extended attribute name is deprecated */ /* The following extended attribute name is deprecated */
{ {
.name = XATTR_CEPH_PREFIX "layout", .name = XATTR_CEPH_PREFIX "layout",
.name_size = sizeof (XATTR_CEPH_PREFIX "layout"),
.getxattr_cb = ceph_vxattrcb_file_layout, .getxattr_cb = ceph_vxattrcb_file_layout,
.readonly = true, .readonly = true,
}, },
{ 0 } /* Required table terminator */ { 0 } /* Required table terminator */
}; };
static size_t ceph_file_vxattrs_name_size; /* total size of all names */
static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode) static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
{ {
...@@ -142,6 +147,46 @@ static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode) ...@@ -142,6 +147,46 @@ static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
return NULL; return NULL;
} }
static size_t ceph_vxattrs_name_size(struct ceph_vxattr *vxattrs)
{
if (vxattrs == ceph_dir_vxattrs)
return ceph_dir_vxattrs_name_size;
if (vxattrs == ceph_file_vxattrs)
return ceph_file_vxattrs_name_size;
BUG();
return 0;
}
/*
* Compute the aggregate size (including terminating '\0') of all
* virtual extended attribute names in the given vxattr table.
*/
static size_t __init vxattrs_name_size(struct ceph_vxattr *vxattrs)
{
struct ceph_vxattr *vxattr;
size_t size = 0;
for (vxattr = vxattrs; vxattr->name; vxattr++)
size += vxattr->name_size;
return size;
}
/* Routines called at initialization and exit time */
void __init ceph_xattr_init(void)
{
ceph_dir_vxattrs_name_size = vxattrs_name_size(ceph_dir_vxattrs);
ceph_file_vxattrs_name_size = vxattrs_name_size(ceph_file_vxattrs);
}
void ceph_xattr_exit(void)
{
ceph_dir_vxattrs_name_size = 0;
ceph_file_vxattrs_name_size = 0;
}
static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode, static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
const char *name) const char *name)
{ {
...@@ -615,11 +660,12 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) ...@@ -615,11 +660,12 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
goto out; goto out;
list_xattr: list_xattr:
vir_namelen = 0; /*
/* include virtual dir xattrs */ * Start with virtual dir xattr names (if any) (including
if (vxattrs) * terminating '\0' characters for each).
for (i = 0; vxattrs[i].name; i++) */
vir_namelen += strlen(vxattrs[i].name) + 1; vir_namelen = ceph_vxattrs_name_size(vxattrs);
/* adding 1 byte per each variable due to the null termination */ /* adding 1 byte per each variable due to the null termination */
namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
err = -ERANGE; err = -ERANGE;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册