From dd7d59a08141d6a24b172c22f5e27c8962e25fb9 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 15 Mar 2017 15:32:47 +0000 Subject: [PATCH] client: getattr before read on ceph.* xattrs Previously we were returning values for quota, layout xattrs without any kind of update -- the user just got whatever happened to be in our cache. Clearly this extra round trip has a cost, but reads of these xattrs are fairly rare, happening on admin intervention rather than in normal operation. Fixes: http://tracker.ceph.com/issues/17939 Signed-off-by: John Spray (cherry picked from commit 532dc4b68e538c189ef828f67cecd0d647a62250) --- src/client/Client.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 616a8b2273cc0..840958e528a98 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -9827,10 +9827,21 @@ int Client::_getxattr(Inode *in, const char *name, void *value, size_t size, if (vxattr) { r = -ENODATA; - char buf[256]; + // Do a force getattr to get the latest quota before returning + // a value to userspace. + r = _getattr(in, 0, perms, true); + if (r != 0) { + // Error from getattr! + return r; + } + // call pointer-to-member function - if (!(vxattr->exists_cb && !(this->*(vxattr->exists_cb))(in))) + char buf[256]; + if (!(vxattr->exists_cb && !(this->*(vxattr->exists_cb))(in))) { r = (this->*(vxattr->getxattr_cb))(in, buf, sizeof(buf)); + } else { + r = -ENODATA; + } if (size != 0) { if (r > (int)size) { -- 2.39.5