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));
+ r = chain_getxattr(candidate_path.c_str(), get_lfn_attr().c_str(),
+ buf, sizeof(buf));
if (r < 0) {
if (errno != ENODATA && errno != ENOENT)
return -errno;
*exists = 1;
return 0;
}
+ r = chain_getxattr(candidate_path.c_str(), get_alt_lfn_attr().c_str(),
+ buf, sizeof(buf));
+ if (r > 0) {
+ buf[MIN((int)sizeof(buf) - 1, r)] = '\0';
+ if (!strcmp(buf, full_name.c_str())) {
+ dout(20) << __func__ << " used alt attr for " << full_name << dendl;
+ if (mangled_name)
+ *mangled_name = candidate;
+ if (out_path)
+ *out_path = candidate_path;
+ if (exists)
+ *exists = 1;
+ return 0;
+ }
+ }
}
assert(0); // Unreachable
return 0;
string full_path = get_full_path(path, mangled_name);
string full_name = lfn_generate_object_name(oid);
maybe_inject_failure();
- return chain_setxattr(full_path.c_str(), get_lfn_attr().c_str(),
+
+ // 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;
+ }
+
+ return chain_setxattr(full_path.c_str(), get_lfn_attr().c_str(),
full_name.c_str(), full_name.size());
}
maybe_inject_failure();
if (r < 0)
return -errno;
- else
- return 0;
} else {
string rename_to = get_full_path(path, mangled_name);
string rename_from = get_full_path(path, lfn_get_short_name(oid, i - 1));
maybe_inject_failure();
if (r < 0)
return -errno;
- else
- return 0;
}
+ return 0;
}
int LFNIndex::lfn_translate(const vector<string> &path,
}
private:
- string lfn_attribute;
+ string lfn_attribute, lfn_alt_attribute;
coll_t collection;
public:
char buf[100];
snprintf(buf, sizeof(buf), "%d", index_version);
lfn_attribute = LFN_ATTR + string(buf);
- }
+ lfn_alt_attribute = LFN_ATTR + string(buf) + "-alt";
+ }
}
coll_t coll() const { return collection; }
const string &get_lfn_attr() const {
return lfn_attribute;
}
+ const string &get_alt_lfn_attr() const {
+ return lfn_alt_attribute;
+ }
/**
* Gets the filename corresponsing to oid in path.