]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
LFNIndex: use chain_getxattr_buf
authorSamuel Just <sjust@redhat.com>
Fri, 8 Apr 2016 18:38:06 +0000 (11:38 -0700)
committerSamuel Just <sjust@redhat.com>
Fri, 8 Apr 2016 22:39:13 +0000 (15:39 -0700)
LFN attrs can be longer than these hard coded limits, let's just do
buffer doubling everywhere.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/os/filestore/LFNIndex.cc

index 26c2fb155a6c78be8d477d8c013578472fd3a614..1994d5ac1ee92935914d842b7fc7d7cb848ca595 100644 (file)
@@ -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<string> &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<void *>(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<string> &path,
@@ -757,12 +749,14 @@ int LFNIndex::lfn_get_name(const vector<string> &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<string> &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<string> &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<string> &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<string> &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<string> &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<false, true>(
-      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<false, true>(
+       full_path.c_str(), get_alt_lfn_attr().c_str(),
+       bp.c_str(), bp.length());
+      if (r < 0)
+       return r;
+    }
   }
 
   return chain_setxattr<false, true>(
@@ -941,31 +942,32 @@ int LFNIndex::lfn_translate(const vector<string> &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);
 }