mds: add osdmap epoch for setxattr of MClientRequest.

Now we use setxattr set file/dir layout. This may need data pool
info. So in mds server, it need check osdmap. At present, if mds
don't find data pool, it will get the latest osdmap. Now if pass osd epoch
as a parameter for setxattr. We can only check this epoch of osdmap.
  But for compatible, we still need old code for old client.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
This commit is contained in:
Jianpeng Ma 2015-08-25 08:29:44 +08:00
parent e20195dfb1
commit 90dea96f70
3 changed files with 32 additions and 10 deletions

View File

@ -409,6 +409,7 @@ union ceph_mds_request_args {
} __attribute__ ((packed)) open;
struct {
__le32 flags;
__le32 osdmap_epoch; /* use for set file/dir layout */
} __attribute__ ((packed)) setxattr;
struct {
struct ceph_file_layout layout;

View File

@ -4019,16 +4019,21 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
rest = name.substr(name.find("layout"));
const OSDMap *osdmap = mds->objecter->get_osdmap_read();
int r = parse_layout_vxattr(rest, value, osdmap, &layout);
epoch_t epoch = osdmap->get_epoch();
mds->objecter->put_osdmap_read();
if (r < 0) {
if (r == -ENOENT) {
if (!mdr->waited_for_osdmap) {
// make sure we have the latest map.
// FIXME: we should get the client's osdmap epoch and just
// make sure we have *that*.
epoch_t req_epoch = req->get_osdmap_epoch();
if (req_epoch > epoch) {
if (!mds->objecter->wait_for_map(req_epoch,
new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher)))
return;
} else if (req_epoch == 0 && !mdr->waited_for_osdmap) {
// For compatibility with client w/ old code, we still need get the latest map.
// One day if COMPACT_VERSION of MClientRequest >=3, we can remove those code.
mdr->waited_for_osdmap = true;
mds->objecter->wait_for_latest_osdmap(
new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
return;
}
r = -EINVAL;
@ -4057,13 +4062,18 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
rest = name.substr(name.find("layout"));
const OSDMap *osdmap = mds->objecter->get_osdmap_read();
int r = parse_layout_vxattr(rest, value, osdmap, &layout);
epoch_t epoch = osdmap->get_epoch();
mds->objecter->put_osdmap_read();
if (r < 0) {
if (r == -ENOENT) {
if (!mdr->waited_for_osdmap) {
// make sure we have the latest map.
// FIXME: we should get the client's osdmap epoch and just
// make sure we have *that*.
epoch_t req_epoch = req->get_osdmap_epoch();
if (req_epoch > epoch) {
if (!mds->objecter->wait_for_map(req_epoch,
new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher)))
return;
} else if (req_epoch == 0 && !mdr->waited_for_osdmap) {
// For compatibility with client w/ old code, we still need get the latest map.
// One day if COMPACT_VERSION of MClientRequest >=3, we can remove those code.
mdr->waited_for_osdmap = true;
mds->objecter->wait_for_latest_osdmap(
new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));

View File

@ -46,7 +46,7 @@
// metadata ops.
class MClientRequest : public Message {
static const int HEAD_VERSION = 2;
static const int HEAD_VERSION = 3;
static const int COMPAT_VERSION = 1;
public:
@ -93,6 +93,17 @@ private:
public:
void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
epoch_t get_mdsmap_epoch() { return head.mdsmap_epoch; }
epoch_t get_osdmap_epoch() const {
assert(head.op == CEPH_MDS_OP_SETXATTR);
if (header.version >= 3)
return head.args.setxattr.osdmap_epoch;
else
return 0;
}
void set_osdmap_epoch(epoch_t e) {
assert(head.op == CEPH_MDS_OP_SETXATTR);
head.args.setxattr.osdmap_epoch = e;
}
metareqid_t get_reqid() {
// FIXME: for now, assume clients always have 1 incarnation