...and encode/decode it appropriately.
The idea of this field is to be advisory, to allow the MDS to handle
things differently if it so chooses. We deliberately do _not_ offer
any firm policy here.
We start with a flag that tells the MDS when an application may end up
blocking on the result of this cap request.
A new "sync" arg is added to send_cap, and we set the new flag in the
cap request based on its value. For now, the callers all set the sync
boolean to false everywhere to preserve the existing behavior.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
}
void Client::send_cap(Inode *in, MetaSession *session, Cap *cap,
- int used, int want, int retain, int flush,
- ceph_tid_t flush_tid)
+ bool sync, int used, int want, int retain,
+ int flush, ceph_tid_t flush_tid)
{
int held = cap->issued | cap->implemented;
int revoking = cap->implemented & ~cap->issued;
ldout(cct, 10) << "send_cap " << *in
<< " mds." << session->mds_num << " seq " << cap->seq
+ << (sync ? " sync " : " async ")
<< " used " << ccap_string(used)
<< " want " << ccap_string(want)
<< " flush " << ccap_string(flush)
m->btime = in->btime;
m->time_warp_seq = in->time_warp_seq;
m->change_attr = in->change_attr;
+ if (sync)
+ m->flags |= CLIENT_CAPS_SYNC;
if (flush & CEPH_CAP_FILE_WR) {
m->inline_version = in->inline_version;
flush_tid = 0;
}
- send_cap(in, session, cap, cap_used, wanted, retain, flushing, flush_tid);
+ send_cap(in, session, cap, false, cap_used, wanted, retain, flushing,
+ flush_tid);
}
}
for (map<ceph_tid_t,int>::iterator p = in->flushing_cap_tids.begin();
p != in->flushing_cap_tids.end();
++p) {
- send_cap(in, session, cap, (get_caps_used(in) | in->caps_dirty()),
+ send_cap(in, session, cap, false, (get_caps_used(in) | in->caps_dirty()),
in->caps_wanted(), (cap->issued | cap->implemented),
p->second, p->first);
}
void handle_cap_flushsnap_ack(MetaSession *session, Inode *in, class MClientCaps *m);
void handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, class MClientCaps *m);
void cap_delay_requeue(Inode *in);
- void send_cap(Inode *in, MetaSession *session, Cap *cap,
+ void send_cap(Inode *in, MetaSession *session, Cap *cap, bool sync,
int used, int want, int retain, int flush,
ceph_tid_t flush_tid);
void check_caps(Inode *in, bool immediate);
#include "msg/Message.h"
#include "include/ceph_features.h"
+#define CLIENT_CAPS_SYNC (0x1)
class MClientCaps : public Message {
- static const int HEAD_VERSION = 9;
+ static const int HEAD_VERSION = 10;
static const int COMPAT_VERSION = 1;
public:
uint32_t caller_uid;
uint32_t caller_gid;
+ /* advisory CLIENT_CAPS_* flags to send to mds */
+ unsigned flags;
+
int get_caps() { return head.caps; }
int get_wanted() { return head.wanted; }
int get_dirty() { return head.dirty; }
time_warp_seq(0),
osd_epoch_barrier(0),
oldest_flush_tid(0),
- caller_uid(0), caller_gid(0) {
+ caller_uid(0), caller_gid(0),
+ flags(0) {
inline_version = 0;
}
MClientCaps(int op,
time_warp_seq(0),
osd_epoch_barrier(oeb),
oldest_flush_tid(0),
- caller_uid(0), caller_gid(0) {
+ caller_uid(0), caller_gid(0),
+ flags(0) {
memset(&head, 0, sizeof(head));
head.op = op;
head.ino = ino;
time_warp_seq(0),
osd_epoch_barrier(oeb),
oldest_flush_tid(0),
- caller_uid(0), caller_gid(0) {
+ caller_uid(0), caller_gid(0),
+ flags(0) {
memset(&head, 0, sizeof(head));
head.op = op;
head.ino = ino;
::decode(btime, p);
::decode(change_attr, p);
}
+ if (header.version >= 10) {
+ ::decode(flags, p);
+ }
}
void encode_payload(uint64_t features) {
header.version = HEAD_VERSION;
::encode(layout.pool_ns, payload);
::encode(btime, payload);
::encode(change_attr, payload);
+ ::encode(flags, payload);
}
};