unsigned char hash_seed; // 0 if not hashed.
int nlink;
bool anchored;
+ __uint64_t file_data_version;
};
// file i/o -----------------------------------------
+__uint64_t MDCache::issue_file_data_version(CInode *in)
+{
+ dout(7) << "issue_file_data_version on " << *in << endl;
+ return in->inode.file_data_version;
+}
int MDCache::issue_file_caps(CInode *in,
dout(7) << " issuing caps " << caps << " (i want " << my_want << ", allowed " << allowed << ")" << endl;
assert(caps > 0);
+ // issuing new write permissions?
+ if ((issued & CFILE_CAP_WR) == 0 &&
+ ( caps & CFILE_CAP_WR) != 0) {
+ dout(7) << " incrementing file_data_version for " << *in << endl;
+ in->inode.file_data_version++;
+ }
+
return caps;
}
// -- file i/o --
+ __uint64_t issue_file_data_version(CInode *in);
int issue_file_caps(CInode *in, int mode, MClientRequest *req);
void eval_file_caps(CInode *in);
void handle_client_file_caps(class MClientFileCaps *m);
// can we issue the caps they want?
+ __uint64_t fdv = mdcache->issue_file_data_version(cur);
int caps = mdcache->issue_file_caps(cur, mode, req);
if (!caps) return; // can't issue (yet), so wait!
// reply
MClientReply *reply = new MClientReply(req, f->fh); // fh # is return code
reply->set_file_caps(caps);
+ reply->set_file_data_version(fdv);
reply_request(req, reply, cur);
}
}
// atime? ****
-
+
+ // were we writing?
+ int had_caps = f->pending_caps & f->confirmed_caps; // safe set of caps the client can assume it had
+
+ if ((f->confirmed_caps | f->pending_caps) & CFILE_CAP_WR != 0) {
+ // inc file_data_version
+ dout(7) << " incrementing file_data_version for " << *cur << endl;
+ cur->inode.file_data_version++;
+ }
+
// close it.
cur->remove_fh(f);
// XXX what about atime?
+
+ // give back a file_data_version to client
+ MClientReply *reply = new MClientReply(req, 0);
+ __uint64_t fdv = mdcache->issue_file_data_version(cur);
+ reply->set_file_caps(had_caps);
+ reply->set_file_data_version(fdv);
+
// commit
- commit_request(req, new MClientReply(req, 0), cur,
+ commit_request(req, reply, cur,
new EInodeUpdate(cur)); // FIXME wrong message?
}
int trace_depth;
int dir_size;
unsigned char file_caps; // for open
+ __uint64_t file_data_version; // for client buffercache consistency
} MClientReply_st;
class MClientReply : public Message {
const vector<c_inode_info*>& get_trace() { return trace; }
vector<c_inode_info*>& get_dir_contents() { return dir_contents; }
unsigned char get_file_caps() { return st.file_caps; }
+ __uint64_t get_file_data_version() { return st.file_data_version; }
void set_result(int r) { st.result = r; }
void set_file_caps(unsigned char c) { st.file_caps = c; }
+ void set_file_data_version(__uint64_t v) { st.file_data_version = v; }
MClientReply() {};
MClientReply(MClientRequest *req, int result = 0) :