From: Samuel Just Date: Fri, 8 Apr 2016 18:38:06 +0000 (-0700) Subject: LFNIndex: use chain_getxattr_buf X-Git-Tag: v10.1.2~7^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cb03d4d3c23ef7a8b6b1080a4100fb3fefe0a015;p=ceph.git LFNIndex: use chain_getxattr_buf LFN attrs can be longer than these hard coded limits, let's just do buffer doubling everywhere. Signed-off-by: Samuel Just --- diff --git a/src/os/filestore/LFNIndex.cc b/src/os/filestore/LFNIndex.cc index 26c2fb155a6c..1994d5ac1ee9 100644 --- a/src/os/filestore/LFNIndex.cc +++ b/src/os/filestore/LFNIndex.cc @@ -383,14 +383,18 @@ static int get_hobject_from_oinfo(const char *dir, const char *file, ghobject_t *o) { char path[PATH_MAX]; - bufferptr bp(PATH_MAX); snprintf(path, sizeof(path), "%s/%s", dir, file); // Hack, user.ceph._ is the attribute used to store the object info - int r = chain_getxattr(path, "user.ceph._", bp.c_str(), bp.length()); + bufferptr bp; + int r = chain_getxattr_buf( + path, + "user.ceph._", + &bp); if (r < 0) return r; bufferlist bl; - bl.push_back(bp); + if (r > 0) + bl.push_back(bp); object_info_t oi(bl); *o = ghobject_t(oi.soid); return 0; @@ -539,26 +543,14 @@ int LFNIndex::get_attr_path(const vector &path, bufferlist &attr_value) { string full_path = get_full_path_subdir(path); - size_t size = 1024; // Initial - while (1) { - bufferptr buf(size); - int r = chain_getxattr(full_path.c_str(), mangle_attr_name(attr_name).c_str(), - reinterpret_cast(buf.c_str()), - size); - if (r > 0) { - buf.set_length(r); - attr_value.push_back(buf); - break; - } else { - r = -errno; - if (r == -ERANGE) { - size *= 2; - } else { - return r; - } - } - } - return 0; + bufferptr bp; + int r = chain_getxattr_buf( + full_path.c_str(), + mangle_attr_name(attr_name).c_str(), + &bp); + if (r > 0) + attr_value.push_back(bp); + return r; } int LFNIndex::remove_attr_path(const vector &path, @@ -757,12 +749,14 @@ int LFNIndex::lfn_get_name(const vector &path, int i = 0; string candidate; string candidate_path; - char buf[FILENAME_MAX_LEN + 1]; for ( ; ; ++i) { candidate = lfn_get_short_name(oid, i); candidate_path = get_full_path(path, candidate); - r = chain_getxattr(candidate_path.c_str(), get_lfn_attr().c_str(), - buf, sizeof(buf)); + bufferptr bp; + r = chain_getxattr_buf( + candidate_path.c_str(), + get_lfn_attr().c_str(), + &bp); if (r < 0) { if (errno != ENODATA && errno != ENOENT) return -errno; @@ -783,8 +777,8 @@ int LFNIndex::lfn_get_name(const vector &path, return 0; } assert(r > 0); - buf[MIN((int)sizeof(buf) - 1, r)] = '\0'; - if (!strcmp(buf, full_name.c_str())) { + string lfn(bp.c_str(), bp.length()); + if (lfn == full_name) { if (mangled_name) *mangled_name = candidate; if (out_path) @@ -796,8 +790,11 @@ int LFNIndex::lfn_get_name(const vector &path, } return 0; } - r = chain_getxattr(candidate_path.c_str(), get_alt_lfn_attr().c_str(), - buf, sizeof(buf)); + bp = bufferptr(); + r = chain_getxattr_buf( + candidate_path.c_str(), + get_alt_lfn_attr().c_str(), + &bp); if (r > 0) { // only consider alt name if nlink > 1 struct stat st; @@ -808,7 +805,7 @@ int LFNIndex::lfn_get_name(const vector &path, // left over from incomplete unlink, remove maybe_inject_failure(); dout(20) << __func__ << " found extra alt attr for " << candidate_path - << ", long name " << string(buf, r) << dendl; + << ", long name " << string(bp.c_str(), bp.length()) << dendl; rc = chain_removexattr(candidate_path.c_str(), get_alt_lfn_attr().c_str()); maybe_inject_failure(); @@ -816,8 +813,8 @@ int LFNIndex::lfn_get_name(const vector &path, return rc; continue; } - buf[MIN((int)sizeof(buf) - 1, r)] = '\0'; - if (!strcmp(buf, full_name.c_str())) { + string lfn(bp.c_str(), bp.length()); + if (lfn == full_name) { dout(20) << __func__ << " used alt attr for " << full_name << dendl; if (mangled_name) *mangled_name = candidate; @@ -844,20 +841,24 @@ int LFNIndex::lfn_created(const vector &path, maybe_inject_failure(); // if the main attr exists and is different, move it to the alt attr. - char buf[FILENAME_MAX_LEN + 1]; - int r = chain_getxattr(full_path.c_str(), get_lfn_attr().c_str(), - buf, sizeof(buf)); - if (r >= 0 && (r != (int)full_name.length() || - memcmp(buf, full_name.c_str(), full_name.length()))) { - dout(20) << __func__ << " " << mangled_name - << " moving old name to alt attr " - << string(buf, r) - << ", new name is " << full_name << dendl; - r = chain_setxattr( - full_path.c_str(), get_alt_lfn_attr().c_str(), - buf, r); - if (r < 0) - return r; + bufferptr bp; + int r = chain_getxattr_buf( + full_path.c_str(), + get_lfn_attr().c_str(), + &bp); + if (r > 0) { + string lfn(bp.c_str(), bp.length()); + if (lfn != full_name) { + dout(20) << __func__ << " " << mangled_name + << " moving old name to alt attr " + << lfn + << ", new name is " << full_name << dendl; + r = chain_setxattr( + full_path.c_str(), get_alt_lfn_attr().c_str(), + bp.c_str(), bp.length()); + if (r < 0) + return r; + } } return chain_setxattr( @@ -941,31 +942,32 @@ int LFNIndex::lfn_translate(const vector &path, return lfn_parse_object_name(short_name, out); } string full_path = get_full_path(path, short_name); - char attr[PATH_MAX]; // First, check alt attr - int r = chain_getxattr( + bufferptr bp; + int r = chain_getxattr_buf( full_path.c_str(), get_alt_lfn_attr().c_str(), - attr, - sizeof(attr) - 1); - if (r >= 0) { + &bp); + if (r > 0) { // There is an alt attr, does it match? - if (r < (int)sizeof(attr)) - attr[r] = '\0'; - if (short_name_matches(short_name.c_str(), attr)) { - string long_name(attr); - return lfn_parse_object_name(long_name, out); + string lfn(bp.c_str(), bp.length()); + if (short_name_matches(short_name.c_str(), lfn.c_str())) { + return lfn_parse_object_name(lfn, out); } } // Get lfn_attr - r = chain_getxattr(full_path.c_str(), get_lfn_attr().c_str(), attr, sizeof(attr) - 1); + bp = bufferptr(); + r = chain_getxattr_buf( + full_path.c_str(), + get_lfn_attr().c_str(), + &bp); if (r < 0) - return -errno; - if (r < (int)sizeof(attr)) - attr[r] = '\0'; + return r; + if (r == 0) + return -EINVAL; - string long_name(attr); + string long_name(bp.c_str(), bp.length()); return lfn_parse_object_name(long_name, out); }