int snap_caps, snap_cap_refs;
unsigned exporting_issued;
int exporting_mds;
- capseq_t exporting_mseq;
+ ceph_seq_t exporting_mseq;
utime_t hold_caps_until;
xlist<Inode*>::item cap_item;
} __attribute__ ((packed));
+/*
+ * Rollover-safe type and comparator for 32-bit sequence numbers.
+ * Comparator returns -1, 0, or 1.
+ */
+typedef __u32 ceph_seq_t;
+
+static inline __s32 ceph_seq_cmp(__u32 a, __u32 b)
+{
+ return ((__s32)a - (__s32)b);
+}
+
+
/*
* "Frags" are a way to describe a subset of a 32-bit number space,
* using a mask and a value to match against that mask. Any given frag
struct ceph_mds_reply_cap cap;
struct ceph_file_layout layout;
struct ceph_timespec ctime, mtime, atime;
- __le64 time_warp_seq;
+ __le32 time_warp_seq;
__le64 size, max_size, truncate_seq;
__le32 mode, uid, gid;
__le32 nlink;
*/
#define CEPH_CAP_EXPIREABLE (CEPH_CAP_PIN|CEPH_CAP_ANY_RDCACHE)
-
static inline int ceph_caps_for_mode(int mode)
{
switch (mode) {
/* filelock */
__le64 size, max_size;
- __le64 truncate_seq;
+ __le32 truncate_seq;
struct ceph_timespec mtime, atime, ctime;
struct ceph_file_layout layout;
- __le64 time_warp_seq;
+ __le32 time_warp_seq;
} __attribute__ ((packed));
/* make sure we haven't seen a higher mseq */
for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
t = rb_entry(p, struct ceph_cap, ci_node);
- if (t->mseq > mseq) {
+ if (ceph_seq_cmp(t->mseq, mseq) > 0) {
dout(10, " higher mseq on cap from mds%d\n",
t->session->s_mds);
remember = 0;
unsigned long ttl_ms = le32_to_cpu(im->ttl_ms);
if (ci->i_cap_exporting_mds >= 0 &&
- ci->i_cap_exporting_mseq < mseq) {
+ ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) {
dout(10, "handle_cap_import inode %p ci %p mds%d mseq %d"
" - cleared exporting from mds%d\n",
inode, ci, mds, mseq,
dout(10, "handle_cap_import inode %p ci %p mds%d mseq %d\n",
inode, ci, mds, mseq);
}
-
+
realm = ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
false);
ceph_add_cap(inode, session, -1, issued, wanted, seq, mseq, realmino,
struct ceph_inode_info *ci = ceph_inode(inode);
int warn = 0;
- if (truncate_seq > ci->i_truncate_seq ||
+ if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
(truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
dout(10, "size %lld -> %llu\n", inode->i_size, size);
inode->i_size = size;
*/
if (timespec_compare(ctime, &inode->i_ctime) > 0)
inode->i_ctime = *ctime;
- if (time_warp_seq > ci->i_time_warp_seq)
+ if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0)
derr(0, "WARNING: %p mds time_warp_seq %llu > %llu\n",
inode, time_warp_seq, ci->i_time_warp_seq);
} else if (issued & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_WRBUFFER)) {
- if (time_warp_seq > ci->i_time_warp_seq) {
+ if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
/* the MDS did a utimes() */
inode->i_ctime = *ctime;
inode->i_mtime = *mtime;
}
} else {
/* we have no write caps; whatever the MDS says is true */
- if (time_warp_seq >= ci->i_time_warp_seq) {
+ if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
inode->i_ctime = *ctime;
inode->i_mtime = *mtime;
inode->i_atime = *atime;
#include "include/buffer.h"
#include "include/xlist.h"
-#include <map>
-using namespace std;
-
#include "config.h"
/*
int32_t issued;
int32_t pending;
snapid_t client_follows;
- capseq_t mseq;
+ ceph_seq_t mseq;
utime_t last_issue_stamp;
Export() {}
- Export(int w, int i, int p, snapid_t cf, capseq_t s, utime_t lis) :
+ Export(int w, int i, int p, snapid_t cf, ceph_seq_t s, utime_t lis) :
wanted(w), issued(i), pending(p), client_follows(cf), mseq(s), last_issue_stamp(lis) {}
void encode(bufferlist &bl) const {
::encode(wanted, bl);
int client;
__u32 _wanted; // what the client wants (ideally)
- //::decode(cap_history, bl);
utime_t last_issue_stamp;
int issued() {
return _pending | _issued;
}
- capseq_t issue(int c) {
+ ceph_seq_t issue(int c) {
_pending = c;
_issued |= c;
//last_issue =
++last_sent;
return last_sent;
}
- void confirm_receipt(capseq_t seq, int caps) {
+ void confirm_receipt(ceph_seq_t seq, int caps) {
if (seq == last_sent)
_pending = _issued = caps;
}
static const int _max_revoke = 3;
__u32 _pending, _issued;
__u32 _revoke_before[_max_revoke]; // caps before this issue
- capseq_t _revoke_seq[_max_revoke];
+ ceph_seq_t _revoke_seq[_max_revoke];
int _num_revoke;
public:
c |= _revoke_before[i];
return c;
}
- capseq_t issue(int c) {
+ ceph_seq_t issue(int c) {
if (_pending & ~c) {
// note _revoked_ caps prior to this revocation
if (_num_revoke < _max_revoke) {
++last_sent;
return last_sent;
}
- void confirm_receipt(capseq_t seq, int caps) {
+ void confirm_receipt(ceph_seq_t seq, int caps) {
_issued = caps;
if (seq == last_sent) {
_pending = caps;
private:
- capseq_t last_sent;
- //capseq_t last_issue;
- capseq_t mseq;
+ ceph_seq_t last_sent;
+ //ceph_seq_t last_issue;
+ ceph_seq_t mseq;
int suppress;
bool stale;
client_follows(0),
session_caps_item(this), rdcaps_list(rl), rdcaps_item(this), snaprealm_caps_item(this) { }
- capseq_t get_mseq() { return mseq; }
+ ceph_seq_t get_mseq() { return mseq; }
- capseq_t get_last_sent() { return last_sent; }
+ ceph_seq_t get_last_sent() { return last_sent; }
utime_t get_last_issue_stamp() { return last_issue_stamp; }
void touch() {
if (rdcaps_item.is_on_xlist())
void set_last_issue_stamp(utime_t t) { last_issue_stamp = t; }
- //capseq_t get_last_issue() { return last_issue; }
+ //ceph_seq_t get_last_issue() { return last_issue; }
bool is_suppress() { return suppress > 0; }
void inc_suppress() { suppress++; }
_wanted = w;
}
- capseq_t get_last_seq() { return last_sent; }
+ ceph_seq_t get_last_seq() { return last_sent; }
void check_rdcaps_list(int o, int n, int ow, int nw)
bool share;
int client;
MClientCaps *ack;
- capseq_t releasecap;
+ ceph_seq_t releasecap;
C_Locker_FileUpdate_finish(Locker *l, CInode *i, Mutation *m, bool e=false, int c=-1,
- MClientCaps *ac = 0, capseq_t rc=0) :
+ MClientCaps *ac = 0, ceph_seq_t rc=0) :
locker(l), in(i), mut(m), share(e), client(c),
ack(ac), releasecap(rc) {
in->get(CInode::PIN_PTRWAITER);
};
void Locker::file_update_finish(CInode *in, Mutation *mut, bool share, int client,
- MClientCaps *ack, capseq_t releasecap)
+ MClientCaps *ack, ceph_seq_t releasecap)
{
dout(10) << "file_update_finish on " << *in << dendl;
in->pop_and_dirty_projected_inode(mut->ls);
in->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryMessage(mds, m));
return;
}
- if (m->get_mseq() < cap->get_mseq()) {
+ if (ceph_seq_cmp(m->get_mseq(), cap->get_mseq()) < 0) {
dout(7) << "handle_client_caps mseq " << m->get_mseq() << " < " << cap->get_mseq()
<< ", dropping" << dendl;
delete m;
<< " on " << *in << dendl;
MClientCaps *ack = 0;
- capseq_t releasecap = 0;
+ ceph_seq_t releasecap = 0;
if (m->get_dirty() && in->is_auth()) {
dout(7) << " flush client" << client << " dirty " << ccap_string(m->get_dirty())
m->get_caps(), 0, m->get_dirty(), 0);
}
if (m->get_caps() == 0) {
- assert(m->get_seq() <= cap->get_last_sent());
+
+ assert(ceph_seq_cmp(m->get_seq(), cap->get_last_sent()) <= 0);
if (m->get_seq() == cap->get_last_sent()) {
dout(7) << " releasing request client" << client << " seq " << m->get_seq() << " on " << *in << dendl;
cap->releasing++;
delete m;
}
-void Locker::_finish_release_cap(CInode *in, int client, capseq_t seq, MClientCaps *ack)
+void Locker::_finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack)
{
dout(10) << "_finish_release_cap client" << client << " seq " << seq << " on " << *in << dendl;
if (cap->releasing) {
dout(10) << " another release attempt in flight, not releasing yet" << dendl;
delete ack;
- } else if (seq < cap->get_last_sent()) {
+ } else if (ceph_seq_cmp(seq, cap->get_last_sent()) < 0) {
dout(10) << " NOT releasing cap client" << client << ", last_sent " << cap->get_last_sent()
<< " > " << seq << dendl;
delete ack;
* if we update, return true; otherwise, false (no updated needed).
*/
bool Locker::_do_cap_update(CInode *in, int dirty, int wanted, snapid_t follows, MClientCaps *m,
- MClientCaps *ack, capseq_t releasecap)
+ MClientCaps *ack, ceph_seq_t releasecap)
{
dout(10) << "_do_cap_update dirty " << ccap_string(dirty)
<< " wanted " << ccap_string(wanted)
<< " for " << *in << dendl;
pi->atime = atime;
}
- if ((dirty & CEPH_CAP_FILE_EXCL) && pi->time_warp_seq < m->get_time_warp_seq()) {
+ if ((dirty & CEPH_CAP_FILE_EXCL) &&
+ ceph_seq_cmp(pi->time_warp_seq, m->get_time_warp_seq()) < 0) {
dout(7) << " time_warp_seq " << pi->time_warp_seq << " -> " << m->get_time_warp_seq()
<< " for " << *in << dendl;
pi->time_warp_seq = m->get_time_warp_seq();
protected:
void handle_client_caps(class MClientCaps *m);
bool _do_cap_update(CInode *in, int had, int wanted, snapid_t follows, MClientCaps *m,
- MClientCaps *ack=0, capseq_t releasecap=0);
- void _finish_release_cap(CInode *in, int client, capseq_t seq, MClientCaps *ack);
+ MClientCaps *ack=0, ceph_seq_t releasecap=0);
+ void _finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack);
void request_inode_file_caps(CInode *in);
void handle_inode_file_caps(class MInodeFileCaps *m);
void file_update_finish(CInode *in, Mutation *mut, bool share, int client,
- MClientCaps *ack, capseq_t releasecap);
+ MClientCaps *ack, ceph_seq_t releasecap);
public:
bool check_inode_max_size(CInode *in, bool forceupdate=false, __u64 newsize=0);
private:
// CAPS
-typedef __u32 capseq_t;
-
inline string gcap_string(int cap)
{
string s;
ceph_file_layout layout;
uint64_t size; // on directory, # dentries
uint64_t max_size; // client(s) are auth to write this much...
- uint64_t truncate_seq;
+ uint32_t truncate_seq;
utime_t mtime; // file data modify time.
utime_t atime; // file data access time.
- uint64_t time_warp_seq; // count of (potential) mtime/atime timewarps (i.e., utimes())
+ uint32_t time_warp_seq; // count of (potential) mtime/atime timewarps (i.e., utimes())
// dirfrag, recursive accounting
frag_info_t dirstat;
int get_caps() { return head.caps; }
int get_wanted() { return head.wanted; }
int get_dirty() { return head.dirty; }
- capseq_t get_seq() { return head.seq; }
- capseq_t get_mseq() { return head.migrate_seq; }
+ ceph_seq_t get_seq() { return head.seq; }
+ ceph_seq_t get_mseq() { return head.migrate_seq; }
inodeno_t get_ino() { return inodeno_t(head.ino); }
inodeno_t get_realm() { return inodeno_t(head.realm); }
__u64 get_size() { return head.size; }
__u64 get_max_size() { return head.max_size; }
- __u64 get_truncate_seq() { return head.truncate_seq; }
+ __u32 get_truncate_seq() { return head.truncate_seq; }
utime_t get_ctime() { return utime_t(head.ctime); }
utime_t get_mtime() { return utime_t(head.mtime); }
utime_t get_atime() { return utime_t(head.atime); }
- __u64 get_time_warp_seq() { return head.time_warp_seq; }
+ __u32 get_time_warp_seq() { return head.time_warp_seq; }
ceph_file_layout& get_layout() { return head.layout; }