]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/chain_xattr: handle read on chnk-aligned xattr
authorSage Weil <sage@redhat.com>
Wed, 18 Mar 2015 20:49:20 +0000 (13:49 -0700)
committerSage Weil <sage@redhat.com>
Fri, 15 May 2015 22:56:57 +0000 (18:56 -0400)
If we wrote an xattr that was a multiple of a chunk, we will try to read
the next chunk and get ENODATA.  If that happens bail out of the loop and
assume we've read the whole thing.

Backport: hammer, firefly
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/chain_xattr.cc
src/test/objectstore/chain_xattr.cc

index 80cd51457856616aa9be03783f42f56ab91bd4b9..b50cade0b578b20c228063f174a7fc31f62c4af6 100644 (file)
@@ -138,6 +138,10 @@ int chain_getxattr(const char *fn, const char *name, void *val, size_t size)
     size -= chunk_size;
 
     r = sys_getxattr(fn, raw_name, (char *)val + pos, chunk_size);
+    if (i && r == -ENODATA) {
+      ret = pos;
+      break;
+    }
     if (r < 0) {
       ret = r;
       break;
@@ -201,6 +205,10 @@ int chain_fgetxattr(int fd, const char *name, void *val, size_t size)
     size -= chunk_size;
 
     r = sys_fgetxattr(fd, raw_name, (char *)val + pos, chunk_size);
+    if (i && r == -ENODATA) {
+      ret = pos;
+      break;
+    }
     if (r < 0) {
       ret = r;
       break;
index 5c77b9520da24a87d0fe6ae6e6e694596592d280..1617fe9038bd07248cb8ecafc174c2f44c14b6f2 100644 (file)
@@ -148,6 +148,44 @@ TEST(chain_xattr, get_and_set) {
   ::unlink(file);
 }
 
+TEST(chain_xattr, chunk_aligned) {
+  const char* file = FILENAME;
+  ::unlink(file);
+  int fd = ::open(file, O_CREAT|O_WRONLY|O_TRUNC, 0700);
+  const string user("user.");
+
+  // set N* chunk size
+  const string name = "user.foo";
+  const string name2 = "user.bar";
+
+  for (int len = CHAIN_XATTR_MAX_BLOCK_LEN - 10;
+       len < CHAIN_XATTR_MAX_BLOCK_LEN + 10;
+       ++len) {
+    cout << len << std::endl;
+    const string x(len, 'x');
+    char buf[len*2];
+    ASSERT_EQ(len, chain_setxattr(file, name.c_str(), x.c_str(), len));
+    char attrbuf[4096];
+    int l = ceph_os_listxattr(file, attrbuf, sizeof(attrbuf));
+    for (char *p = attrbuf; p - attrbuf < l; p += strlen(p) + 1) {
+      cout << "  attr " << p << std::endl;
+    }
+    ASSERT_EQ(len, chain_getxattr(file, name.c_str(), buf, len*2));
+    ASSERT_EQ(0, chain_removexattr(file, name.c_str()));
+
+    ASSERT_EQ(len, chain_fsetxattr(fd, name2.c_str(), x.c_str(), len));
+    l = ceph_os_flistxattr(fd, attrbuf, sizeof(attrbuf));
+    for (char *p = attrbuf; p - attrbuf < l; p += strlen(p) + 1) {
+      cout << "  attr " << p << std::endl;
+    }
+    ASSERT_EQ(len, chain_fgetxattr(fd, name2.c_str(), buf, len*2));
+    ASSERT_EQ(0, chain_fremovexattr(fd, name2.c_str()));
+  }
+
+  ::close(fd);
+  ::unlink(file);
+}
+
 TEST(chain_xattr, listxattr) {
   const char* file = FILENAME;
   ::unlink(file);