in = diri;
pdn = in->get_parent_dn();
}
- vector<int64_t>::iterator i = inode.old_pools.begin();
- while(i != inode.old_pools.end()) {
+ for (compact_set<int64_t>::iterator i = inode.old_pools.begin();
+ i != inode.old_pools.end();
+ ++i) {
// don't add our own pool id to old_pools to avoid looping (e.g. setlayout 0, 1, 0)
- if (*i == pool) {
- ++i;
- continue;
- }
- bt.old_pools.insert(*i);
- ++i;
+ if (*i != pool)
+ bt.old_pools.insert(*i);
}
}
mdcache->mds->objecter->mutate(oid, oloc, op, snapc, ceph_clock_now(g_ceph_context),
0, NULL, gather.new_sub());
- set<int64_t> old_pools;
- for (vector<int64_t>::iterator p = inode.old_pools.begin();
- p != inode.old_pools.end();
- ++p) {
- if (*p == pool || old_pools.count(*p))
+ for (compact_set<int64_t>::iterator p = inode.old_pools.begin();
+ p != inode.old_pools.end();
+ ++p) {
+ if (*p == pool)
continue;
ObjectOperation op;
object_locator_t oloc(*p);
mdcache->mds->objecter->mutate(oid, oloc, op, snapc, ceph_clock_now(g_ceph_context),
0, NULL, gather.new_sub());
- old_pools.insert(*p);
}
gather.activate();
}
::encode(inode.truncate_size, bl);
::encode(inode.client_ranges, bl);
::encode(inode.inline_data, bl);
- ::encode(inode.inline_version, bl);
}
} else {
// treat flushing as dirty when rejoining cache
::decode(inode.truncate_size, p);
::decode(inode.client_ranges, p);
::decode(inode.inline_data, p);
- ::decode(inode.inline_version, p);
}
} else {
bool replica_dirty;
} else {
allowed = get_caps_allowed_by_type(CAP_ANY);
}
- if (inode.inline_version != CEPH_INLINE_NONE &&
+ if (inode.inline_data.version != CEPH_INLINE_NONE &&
!mdcache->mds->get_session(client)->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA))
allowed &= ~(CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR);
return allowed;
// inline data
version_t inline_version = 0;
bufferlist inline_data;
- if (i->inline_version == CEPH_INLINE_NONE) {
+ if (i->inline_data.version == CEPH_INLINE_NONE) {
inline_version = CEPH_INLINE_NONE;
} else if ((!cap && !no_caps) ||
- (cap && cap->client_inline_version < i->inline_version) ||
+ (cap && cap->client_inline_version < i->inline_data.version) ||
(getattr_caps & CEPH_CAP_FILE_RD)) { // client requests inline data
- inline_version = i->inline_version;
- inline_data = i->inline_data;
+ inline_version = i->inline_data.version;
+ if (i->inline_data.length() > 0)
+ inline_data = i->inline_data.get_data();
}
// nest (do same as file... :/)
i->atime.encode_timeval(&m->head.atime);
m->head.time_warp_seq = i->time_warp_seq;
- if (cap->client_inline_version < i->inline_version) {
- m->inline_version = cap->client_inline_version = i->inline_version;
- m->inline_data = i->inline_data;
+ if (cap->client_inline_version < i->inline_data.version) {
+ m->inline_version = cap->client_inline_version = i->inline_data.version;
+ if (i->inline_data.length() > 0)
+ m->inline_data = i->inline_data.get_data();
} else {
m->inline_version = 0;
}
allowed |= xlocker_allowed & in->get_xlocker_mask(it->first);
Session *session = mds->get_session(it->first);
- if (in->inode.inline_version != CEPH_INLINE_NONE &&
+ if (in->inode.inline_data.version != CEPH_INLINE_NONE &&
!(session && session->connection &&
session->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA)))
allowed &= ~(CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR);
}
if (in->inode.is_file() &&
(dirty & CEPH_CAP_FILE_WR) &&
- inline_version > pi->inline_version) {
- pi->inline_version = inline_version;
- pi->inline_data = m->inline_data;
+ inline_version > pi->inline_data.version) {
+ pi->inline_data.version = inline_version;
+ if (inline_version != CEPH_INLINE_NONE && m->inline_data.length() > 0)
+ pi->inline_data.get_data() = m->inline_data;
+ else
+ pi->inline_data.free_data();
}
if ((dirty & CEPH_CAP_FILE_EXCL) && atime != pi->atime) {
dout(7) << " atime " << pi->atime << " -> " << atime
NULL, gather.new_sub());
}
// remove old backtrace objects
- for (vector<int64_t>::iterator p = pi->old_pools.begin();
+ for (compact_set<int64_t>::iterator p = pi->old_pools.begin();
p != pi->old_pools.end();
++p) {
object_locator_t oloc(*p);
if (!mds->mdsmap->get_inline_data_enabled() ||
!mdr->session->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA))
- in->inode.inline_version = CEPH_INLINE_NONE;
+ in->inode.inline_data.version = CEPH_INLINE_NONE;
mdcache->add_inode(in); // add
dout(10) << "prepare_new_inode " << *in << dendl;
return;
}
- if (cur->inode.inline_version != CEPH_INLINE_NONE &&
+ if (cur->inode.inline_data.version != CEPH_INLINE_NONE &&
!mdr->session->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA)) {
dout(7) << "old client cannot open inline data file " << *cur << dendl;
respond_to_request(mdr, -EPERM);
return out << r.range.first << '-' << r.range.last << "@" << r.follows;
}
+/*
+ * inline_data_t
+ */
+void inline_data_t::encode(bufferlist &bl) const
+{
+ ::encode(version, bl);
+ if (blp)
+ ::encode(*blp, bl);
+ else
+ ::encode(bufferlist(), bl);
+}
+void inline_data_t::decode(bufferlist::iterator &p)
+{
+ ::decode(version, p);
+ uint32_t inline_len;
+ ::decode(inline_len, p);
+ if (inline_len > 0)
+ ::decode_nohead(inline_len, get_data(), p);
+ else
+ free_data();
+}
/*
* inode_t
::encode(backtrace_version, bl);
::encode(old_pools, bl);
::encode(max_size_ever, bl);
- ::encode(inline_version, bl);
::encode(inline_data, bl);
-
::encode(quota, bl);
ENCODE_FINISH(bl);
if (struct_v >= 8)
::decode(max_size_ever, p);
if (struct_v >= 9) {
- ::decode(inline_version, p);
::decode(inline_data, p);
} else {
- inline_version = CEPH_INLINE_NONE;
+ inline_data.version = CEPH_INLINE_NONE;
}
if (struct_v < 10)
backtrace_version = 0; // force update backtrace
f->close_section();
f->open_array_section("old_pools");
- vector<int64_t>::const_iterator i = old_pools.begin();
- while(i != old_pools.end()) {
+ for (compact_set<int64_t>::const_iterator i = old_pools.begin();
+ i != old_pools.end();
+ ++i)
f->dump_int("pool", *i);
- }
f->close_section();
f->dump_unsigned("size", size);
mtime != other.mtime ||
atime != other.atime ||
time_warp_seq != other.time_warp_seq ||
- !(*const_cast<bufferlist*>(&inline_data) ==
- *const_cast<bufferlist*>(&other.inline_data)) ||
- inline_version != other.inline_version ||
+ inline_data != other.inline_data ||
client_ranges != other.client_ranges ||
!(dirstat == other.dirstat) ||
!(rstat == other.rstat) ||
if (max_size_ever < other.max_size_ever ||
truncate_seq < other.truncate_seq ||
time_warp_seq < other.time_warp_seq ||
- inline_version < other.inline_version ||
+ inline_data.version < other.inline_data.version ||
dirstat.version < other.dirstat.version ||
rstat.version < other.rstat.version ||
accounted_rstat.version < other.accounted_rstat.version ||
#include "include/xlist.h"
#include "include/interval_set.h"
#include "include/compact_map.h"
+#include "include/compact_set.h"
#include "inode_backtrace.h"
l.follows == r.follows;
}
+struct inline_data_t {
+private:
+ bufferlist *blp;
+public:
+ version_t version;
+
+ void free_data() {
+ delete blp;
+ blp = NULL;
+ }
+ bufferlist& get_data() {
+ if (!blp)
+ blp = new bufferlist;
+ return *blp;
+ }
+ size_t length() const { return blp ? blp->length() : 0; }
+
+ inline_data_t() : blp(0), version(1) {}
+ inline_data_t(const inline_data_t& o) : blp(0), version(o.version) {
+ if (o.blp)
+ get_data() = *o.blp;
+ }
+ ~inline_data_t() {
+ free_data();
+ }
+ inline_data_t& operator=(const inline_data_t& o) {
+ version = o.version;
+ if (o.blp)
+ get_data() = *o.blp;
+ else
+ free_data();
+ return *this;
+ }
+ bool operator==(const inline_data_t& o) const {
+ return length() == o.length() &&
+ (length() == 0 ||
+ (*const_cast<bufferlist*>(blp) == *const_cast<bufferlist*>(o.blp)));
+ }
+ bool operator!=(const inline_data_t& o) const {
+ return !(*this == o);
+ }
+ void encode(bufferlist &bl) const;
+ void decode(bufferlist::iterator& bl);
+};
+WRITE_CLASS_ENCODER(inline_data_t)
/*
* inode_t
// file (data access)
ceph_dir_layout dir_layout; // [dir only]
ceph_file_layout layout;
- vector <int64_t> old_pools;
+ compact_set <int64_t> old_pools;
uint64_t size; // on directory, # dentries
uint64_t max_size_ever; // max size the file has ever been
uint32_t truncate_seq;
utime_t mtime; // file data modify time.
utime_t atime; // file data access time.
uint32_t time_warp_seq; // count of (potential) mtime/atime timewarps (i.e., utimes())
- bufferlist inline_data;
- version_t inline_version;
+ inline_data_t inline_data;
std::map<client_t,client_writeable_range_t> client_ranges; // client(s) can write to these ranges
truncate_seq(0), truncate_size(0), truncate_from(0),
truncate_pending(0),
time_warp_seq(0),
- inline_version(1),
version(0), file_data_version(0), xattr_version(0), backtrace_version(0) {
clear_layout();
memset(&dir_layout, 0, sizeof(dir_layout));
void add_old_pool(int64_t l) {
backtrace_version = version;
- old_pools.push_back(l);
+ old_pools.insert(l);
}
void encode(bufferlist &bl) const;