diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2014-03-24 01:00:54 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2014-04-05 00:07:19 -0400 |
commit | 1e5c6649ff0a2049511bafa297277234011a5c58 (patch) | |
tree | 3ca17fdb82efe6d3b80158bcc08af58e9fc5c1af /fs/ceph | |
parent | 00bd8edb861eb41d274938cfc0338999d9c593a3 (diff) |
ceph: check buffer size in ceph_vxattrcb_layout()
If buffer size is zero, return the size of layout vxattr. If buffer
size is not zero, check if it is large enough for layout vxattr.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/xattr.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 2dbd668d590b..28549d5f2789 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -64,32 +64,48 @@ static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, | 66 | static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, |
67 | size_t size) | 67 | size_t size) |
68 | { | 68 | { |
69 | int ret; | 69 | int ret; |
70 | struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); | 70 | struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); |
71 | struct ceph_osd_client *osdc = &fsc->client->osdc; | 71 | struct ceph_osd_client *osdc = &fsc->client->osdc; |
72 | s64 pool = ceph_file_layout_pg_pool(ci->i_layout); | 72 | s64 pool = ceph_file_layout_pg_pool(ci->i_layout); |
73 | const char *pool_name; | 73 | const char *pool_name; |
74 | char buf[128]; | ||
74 | 75 | ||
75 | dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode); | 76 | dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode); |
76 | down_read(&osdc->map_sem); | 77 | down_read(&osdc->map_sem); |
77 | pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool); | 78 | pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool); |
78 | if (pool_name) | 79 | if (pool_name) { |
79 | ret = snprintf(val, size, | 80 | size_t len = strlen(pool_name); |
80 | "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%s", | 81 | ret = snprintf(buf, sizeof(buf), |
82 | "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=", | ||
81 | (unsigned long long)ceph_file_layout_su(ci->i_layout), | 83 | (unsigned long long)ceph_file_layout_su(ci->i_layout), |
82 | (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), | 84 | (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), |
83 | (unsigned long long)ceph_file_layout_object_size(ci->i_layout), | 85 | (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); |
84 | pool_name); | 86 | if (!size) { |
85 | else | 87 | ret += len; |
86 | ret = snprintf(val, size, | 88 | } else if (ret + len > size) { |
89 | ret = -ERANGE; | ||
90 | } else { | ||
91 | memcpy(val, buf, ret); | ||
92 | memcpy(val + ret, pool_name, len); | ||
93 | ret += len; | ||
94 | } | ||
95 | } else { | ||
96 | ret = snprintf(buf, sizeof(buf), | ||
87 | "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld", | 97 | "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld", |
88 | (unsigned long long)ceph_file_layout_su(ci->i_layout), | 98 | (unsigned long long)ceph_file_layout_su(ci->i_layout), |
89 | (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), | 99 | (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), |
90 | (unsigned long long)ceph_file_layout_object_size(ci->i_layout), | 100 | (unsigned long long)ceph_file_layout_object_size(ci->i_layout), |
91 | (unsigned long long)pool); | 101 | (unsigned long long)pool); |
92 | 102 | if (size) { | |
103 | if (ret <= size) | ||
104 | memcpy(val, buf, ret); | ||
105 | else | ||
106 | ret = -ERANGE; | ||
107 | } | ||
108 | } | ||
93 | up_read(&osdc->map_sem); | 109 | up_read(&osdc->map_sem); |
94 | return ret; | 110 | return ret; |
95 | } | 111 | } |