summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-10 16:51:19 -0700
committerDavid Zafman <david.zafman@inktank.com>2013-10-03 15:23:02 -0700
commit1aef7bfc8f2fa3104e0e558e7877f84b7fb7ce8c (patch)
tree91480c7dd027172ac75e3b761d948b5cd9ae1b65
parentd82b0bb3dff5e8872c1171ac28e3c01894e62882 (diff)
downloadceph-1aef7bfc8f2fa3104e0e558e7877f84b7fb7ce8c.tar.gz
mds: include requested caps (namely, xattrs) on getattr reply
For xattrs, we only include them in the reply if we are issuing caps on them. However, in the getattr case, we need to include the snapshot of the current state. The original problem is reproduced by LibCephFS.Xattrs_ll (a simple set then get). Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mds/CInode.cc8
-rw-r--r--src/mds/CInode.h3
-rw-r--r--src/mds/Mutation.h4
-rw-r--r--src/mds/Server.cc6
4 files changed, 16 insertions, 5 deletions
diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc
index 7accc5a4dba..4a45d7ac0b1 100644
--- a/src/mds/CInode.cc
+++ b/src/mds/CInode.cc
@@ -2728,8 +2728,10 @@ void CInode::replicate_relax_locks()
// =============================================
int CInode::encode_inodestat(bufferlist& bl, Session *session,
- SnapRealm *dir_realm,
- snapid_t snapid, unsigned max_bytes)
+ SnapRealm *dir_realm,
+ snapid_t snapid,
+ unsigned max_bytes,
+ int getattr_caps)
{
int client = session->info.inst.name.num();
assert(snapid);
@@ -2939,7 +2941,7 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
// include those xattrs?
if (xbl.length() && cap) {
- if (cap->pending() & CEPH_CAP_XATTR_SHARED) {
+ if ((cap->pending() | getattr_caps) & CEPH_CAP_XATTR_SHARED) {
dout(10) << "including xattrs version " << i->xattr_version << dendl;
cap->client_xattr_version = i->xattr_version;
} else {
diff --git a/src/mds/CInode.h b/src/mds/CInode.h
index 1c2a9339c1c..d130b1e5480 100644
--- a/src/mds/CInode.h
+++ b/src/mds/CInode.h
@@ -599,7 +599,8 @@ private:
// for giving to clients
int encode_inodestat(bufferlist& bl, Session *session, SnapRealm *realm,
- snapid_t snapid=CEPH_NOSNAP, unsigned max_bytes=0);
+ snapid_t snapid=CEPH_NOSNAP, unsigned max_bytes=0,
+ int getattr_wants=0);
void encode_cap_message(MClientCaps *m, Capability *cap);
diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h
index b50a03cefa4..94e29fce434 100644
--- a/src/mds/Mutation.h
+++ b/src/mds/Mutation.h
@@ -178,6 +178,7 @@ struct MDRequest : public Mutation {
int snap_caps;
bool did_early_reply;
bool o_trunc; ///< request is an O_TRUNC mutation
+ int getattr_caps; ///< caps requested by getattr
bufferlist reply_extra_bl;
@@ -250,6 +251,7 @@ struct MDRequest : public Mutation {
client_request(0), straydn(NULL), snapid(CEPH_NOSNAP), tracei(0), tracedn(0),
alloc_ino(0), used_prealloc_ino(0), snap_caps(0), did_early_reply(false),
o_trunc(false),
+ getattr_caps(0),
slave_request(0),
internal_op(-1),
retry(0),
@@ -264,6 +266,7 @@ struct MDRequest : public Mutation {
client_request(req), straydn(NULL), snapid(CEPH_NOSNAP), tracei(0), tracedn(0),
alloc_ino(0), used_prealloc_ino(0), snap_caps(0), did_early_reply(false),
o_trunc(false),
+ getattr_caps(0),
slave_request(0),
internal_op(-1),
retry(0),
@@ -278,6 +281,7 @@ struct MDRequest : public Mutation {
client_request(0), straydn(NULL), snapid(CEPH_NOSNAP), tracei(0), tracedn(0),
alloc_ino(0), used_prealloc_ino(0), snap_caps(0), did_early_reply(false),
o_trunc(false),
+ getattr_caps(0),
slave_request(0),
internal_op(-1),
retry(0),
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index bb854f3045f..bf0fcd1e089 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -1034,7 +1034,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply,
// inode
if (in) {
- in->encode_inodestat(bl, session, NULL, snapid);
+ in->encode_inodestat(bl, session, NULL, snapid, 0, mdr->getattr_caps);
dout(20) << "set_trace_dist added in " << *in << dendl;
reply->head.is_target = 1;
} else
@@ -2282,6 +2282,10 @@ void Server::handle_client_getattr(MDRequest *mdr, bool is_lookup)
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
return;
+ // note which caps are requested, so we return at least a snapshot
+ // value for them. (currently this only matters for xattrs)
+ mdr->getattr_caps = mask;
+
mds->balancer->hit_inode(ceph_clock_now(g_ceph_context), ref, META_POP_IRD,
mdr->client_request->get_source().num());