summaryrefslogtreecommitdiff
path: root/src/mds/AnchorClient.cc
blob: fb1b4abb7f959ae99c2f6ace1309038b716f827d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software 
 * Foundation.  See file COPYING.
 * 
 */

#include "common/config.h"
#include "msg/Messenger.h"
#include "global/debug.h"

#include "messages/MMDSTableRequest.h"

#include "LogSegment.h"
#include "MDS.h"

#include "AnchorClient.h"

#define dout_subsys ceph_subsys_mds
#undef dout_prefix
#define dout_prefix *_dout << "mds." << mds->get_nodeid() << ".anchorclient "


// LOOKUPS
/* This function DOES NOT put the passed message before returning */
void AnchorClient::handle_query_result(class MMDSTableRequest *m)
{
  dout(10) << "handle_anchor_reply " << *m << dendl;

  inodeno_t ino;
  vector<Anchor> trace;

  bufferlist::iterator p = m->bl.begin();
  ::decode(ino, p);
  ::decode(trace, p);

  assert(pending_lookup.count(ino));
  list<_pending_lookup> ls;
  ls.swap(pending_lookup[ino]);
  pending_lookup.erase(ino);

  for (list<_pending_lookup>::iterator q = ls.begin(); q != ls.end(); q++) {
    *q->trace = trace;
    if (q->onfinish) {
      q->onfinish->finish(0);
      delete q->onfinish;
    }
  }
}

void AnchorClient::resend_queries()
{
  // resend any pending lookups.
  for (map<inodeno_t, list<_pending_lookup> >::iterator p = pending_lookup.begin();
       p != pending_lookup.end();
       p++) {
    dout(10) << "resending lookup on " << p->first << dendl;
    _lookup(p->first);
  }
}

void AnchorClient::lookup(inodeno_t ino, vector<Anchor>& trace, Context *onfinish)
{
  _pending_lookup l;
  l.onfinish = onfinish;
  l.trace = &trace;

  bool isnew = (pending_lookup.count(ino) == 0);
  pending_lookup[ino].push_back(l);
  if (isnew)
    _lookup(ino);
}

void AnchorClient::_lookup(inodeno_t ino)
{
  MMDSTableRequest *req = new MMDSTableRequest(table, TABLESERVER_OP_QUERY, 0, 0);
  ::encode(ino, req->bl);
  mds->send_message_mds(req, mds->mdsmap->get_tableserver());
}


// FRIENDLY PREPARE

void AnchorClient::prepare_create(inodeno_t ino, vector<Anchor>& trace, 
				  version_t *patid, Context *onfinish)
{
  dout(10) << "prepare_create " << ino << " " << trace << dendl;
  bufferlist bl;
  __u32 op = TABLE_OP_CREATE;
  ::encode(op, bl);
  ::encode(ino, bl);
  ::encode(trace, bl);
  _prepare(bl, patid, 0, onfinish);
}

void AnchorClient::prepare_destroy(inodeno_t ino, 
				   version_t *patid, Context *onfinish)
{
  dout(10) << "prepare_destroy " << ino << dendl;
  bufferlist bl;
  __u32 op = TABLE_OP_DESTROY;
  ::encode(op, bl);
  ::encode(ino, bl);
  _prepare(bl, patid, 0, onfinish);
}


void AnchorClient::prepare_update(inodeno_t ino, vector<Anchor>& trace, 
				  version_t *patid, Context *onfinish)
{
  dout(10) << "prepare_update " << ino << " " << trace << dendl;
  bufferlist bl;
  __u32 op = TABLE_OP_UPDATE;
  ::encode(op, bl);
  ::encode(ino, bl);
  ::encode(trace, bl);
  _prepare(bl, patid, 0, onfinish);
}