~ubuntu-branches/ubuntu/trusty/ceph/trusty-updates

« back to all changes in this revision

Viewing changes to src/mds/Server.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-04-09 11:14:03 UTC
  • mfrom: (1.1.33)
  • Revision ID: package-import@ubuntu.com-20140409111403-jlql95pa8kg1nk9a
Tags: 0.79-0ubuntu1
* New upstream release (LP: #1278466):
  - d/p/modules.patch: Refreshed.
  - d/ceph.install: Install all jerasure modules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
271
271
  for (set<client_t>::iterator p = client_set.begin(); p != client_set.end(); ++p) {
272
272
    Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(p->v));
273
273
    assert(session);
274
 
    if (session->is_stale() ||
 
274
    if (!session->is_open() ||
275
275
        !session->connection.get() ||
276
276
        !session->connection->has_feature(CEPH_FEATURE_EXPORT_PEER))
277
277
      continue;
1679
1679
  if (fail) {
1680
1680
    mdr->drop_local_auth_pins();  // just in case
1681
1681
  } else {
 
1682
    /* freeze authpin wrong inode */
 
1683
    if (mdr->has_more() && mdr->more()->is_freeze_authpin &&
 
1684
        mdr->more()->rename_inode != auth_pin_freeze)
 
1685
      mdr->unfreeze_auth_pin(true);
 
1686
 
1682
1687
    /* handle_slave_rename_prep() call freeze_inode() to wait for all other operations
1683
1688
     * on the source inode to complete. This happens after all locks for the rename
1684
1689
     * operation are acquired. But to acquire locks, we need auth pin locks' parent
2401
2406
  }
2402
2407
 
2403
2408
  if (want_parent) {
 
2409
    if (in->is_base()) {
 
2410
      reply_request(mdr, -EINVAL);
 
2411
      return;
 
2412
    }
2404
2413
    if (!diri || diri->is_stray()) {
2405
2414
      reply_request(mdr, -ESTALE);
2406
2415
      return;
2838
2847
  if (!dir->is_complete()) {
2839
2848
    if (dir->is_frozen()) {
2840
2849
      dout(7) << "dir is frozen " << *dir << dendl;
 
2850
      mds->locker->drop_locks(mdr);
 
2851
      mdr->drop_local_auth_pins();
2841
2852
      dir->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr));
2842
2853
      return;
2843
2854
    }
4484
4495
  }
4485
4496
};
4486
4497
 
 
4498
class C_MDS_SlaveLinkCommit : public Context {
 
4499
  Server *server;
 
4500
  MDRequest *mdr;
 
4501
  CInode *targeti;
 
4502
public:
 
4503
  C_MDS_SlaveLinkCommit(Server *s, MDRequest *r, CInode *t) :
 
4504
    server(s), mdr(r), targeti(t) { }
 
4505
  void finish(int r) {
 
4506
    server->_commit_slave_link(mdr, r, targeti);
 
4507
  }
 
4508
};
 
4509
 
4487
4510
/* This function DOES put the mdr->slave_request before returning*/
4488
4511
void Server::handle_slave_link_prep(MDRequest *mdr)
4489
4512
{
4562
4585
  mdcache->predirty_journal_parents(mdr, &le->commit, dnl->get_inode(), 0, PREDIRTY_SHALLOW|PREDIRTY_PRIMARY, 0);
4563
4586
  mdcache->journal_dirty_inode(mdr, &le->commit, targeti);
4564
4587
 
 
4588
  // set up commit waiter
 
4589
  mdr->more()->slave_commit = new C_MDS_SlaveLinkCommit(this, mdr, targeti);
 
4590
 
4565
4591
  mdlog->submit_entry(le, new C_MDS_SlaveLinkPrep(this, mdr, targeti));
4566
4592
  mdlog->flush();
4567
4593
}
4568
4594
 
4569
 
class C_MDS_SlaveLinkCommit : public Context {
4570
 
  Server *server;
4571
 
  MDRequest *mdr;
4572
 
  CInode *targeti;
4573
 
public:
4574
 
  C_MDS_SlaveLinkCommit(Server *s, MDRequest *r, CInode *t) :
4575
 
    server(s), mdr(r), targeti(t) { }
4576
 
  void finish(int r) {
4577
 
    server->_commit_slave_link(mdr, r, targeti);
4578
 
  }
4579
 
};
4580
 
 
4581
4595
void Server::_logged_slave_link(MDRequest *mdr, CInode *targeti) 
4582
4596
{
4583
4597
  dout(10) << "_logged_slave_link " << *mdr
4592
4606
  // hit pop
4593
4607
  mds->balancer->hit_inode(mdr->now, targeti, META_POP_IWR);
4594
4608
 
 
4609
  // done.
 
4610
  mdr->slave_request->put();
 
4611
  mdr->slave_request = 0;
 
4612
 
4595
4613
  // ack
4596
 
  MMDSSlaveRequest *reply = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
4597
 
                                                 MMDSSlaveRequest::OP_LINKPREPACK);
4598
 
  mds->send_message_mds(reply, mdr->slave_to_mds);
4599
 
  
4600
 
  // set up commit waiter
4601
 
  mdr->more()->slave_commit = new C_MDS_SlaveLinkCommit(this, mdr, targeti);
4602
 
 
4603
 
  // done.
4604
 
  mdr->slave_request->put();
4605
 
  mdr->slave_request = 0;
 
4614
  if (!mdr->aborted) {
 
4615
    MMDSSlaveRequest *reply = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
 
4616
                                                   MMDSSlaveRequest::OP_LINKPREPACK);
 
4617
    mds->send_message_mds(reply, mdr->slave_to_mds);
 
4618
  } else {
 
4619
    dout(10) << " abort flag set, finishing" << dendl;
 
4620
    mdcache->request_finish(mdr);
 
4621
  }
4606
4622
}
4607
4623
 
4608
4624
 
5132
5148
  }
5133
5149
};
5134
5150
 
 
5151
struct C_MDS_SlaveRmdirCommit : public Context {
 
5152
  Server *server;
 
5153
  MDRequest *mdr;
 
5154
  C_MDS_SlaveRmdirCommit(Server *s, MDRequest *r)
 
5155
    : server(s), mdr(r) { }
 
5156
  void finish(int r) {
 
5157
    server->_commit_slave_rmdir(mdr, r);
 
5158
  }
 
5159
};
 
5160
 
5135
5161
void Server::handle_slave_rmdir_prep(MDRequest *mdr)
5136
5162
{
5137
5163
  dout(10) << "handle_slave_rmdir_prep " << *mdr 
5181
5207
 
5182
5208
  mds->mdcache->project_subtree_rename(in, dn->get_dir(), straydn->get_dir());
5183
5209
 
 
5210
  // set up commit waiter
 
5211
  mdr->more()->slave_commit = new C_MDS_SlaveRmdirCommit(this, mdr);
 
5212
 
5184
5213
  mdlog->submit_entry(le, new C_MDS_SlaveRmdirPrep(this, mdr, dn, straydn));
5185
5214
  mdlog->flush();
5186
5215
}
5187
5216
 
5188
 
struct C_MDS_SlaveRmdirCommit : public Context {
5189
 
  Server *server;
5190
 
  MDRequest *mdr;
5191
 
  C_MDS_SlaveRmdirCommit(Server *s, MDRequest *r)
5192
 
    : server(s), mdr(r) { }
5193
 
  void finish(int r) {
5194
 
    server->_commit_slave_rmdir(mdr, r);
5195
 
  }
5196
 
};
5197
 
 
5198
5217
void Server::_logged_slave_rmdir(MDRequest *mdr, CDentry *dn, CDentry *straydn)
5199
5218
{
5200
5219
  dout(10) << "_logged_slave_rmdir " << *mdr << " on " << *dn << dendl;
5207
5226
  dn->pop_projected_linkage();
5208
5227
  mdcache->adjust_subtree_after_rename(in, dn->get_dir(), true);
5209
5228
 
5210
 
  MMDSSlaveRequest *reply = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
5211
 
                                                 MMDSSlaveRequest::OP_RMDIRPREPACK);
5212
 
  mds->send_message_mds(reply, mdr->slave_to_mds);
5213
 
 
5214
 
  // set up commit waiter
5215
 
  mdr->more()->slave_commit = new C_MDS_SlaveRmdirCommit(this, mdr);
5216
 
 
5217
5229
  // done.
5218
5230
  mdr->slave_request->put();
5219
5231
  mdr->slave_request = 0;
5220
5232
  mdr->straydn = 0;
 
5233
 
 
5234
  if (!mdr->aborted) {
 
5235
    MMDSSlaveRequest *reply = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
 
5236
                                                   MMDSSlaveRequest::OP_RMDIRPREPACK);
 
5237
    mds->send_message_mds(reply, mdr->slave_to_mds);
 
5238
  } else {
 
5239
    dout(10) << " abort flag set, finishing" << dendl;
 
5240
    mdcache->request_finish(mdr);
 
5241
  }
5221
5242
}
5222
5243
 
5223
5244
void Server::handle_slave_rmdir_prep_ack(MDRequest *mdr, MMDSSlaveRequest *ack)
5288
5309
  assert(mdr || mds->is_resolve());
5289
5310
 
5290
5311
  CDir *dir = mds->mdcache->get_dirfrag(rollback.src_dir);
 
5312
  if (!dir)
 
5313
    dir = mds->mdcache->get_dirfrag(rollback.src_dir.ino, rollback.src_dname);
5291
5314
  assert(dir);
5292
5315
  CDentry *dn = dir->lookup(rollback.src_dname);
5293
5316
  assert(dn);
5629
5652
  else
5630
5653
    witnesses.insert(srcdn->authority().first);
5631
5654
  destdn->list_replicas(witnesses);
 
5655
  if (destdnl->is_remote() && !oldin->is_auth())
 
5656
    witnesses.insert(oldin->authority().first);
5632
5657
  dout(10) << " witnesses " << witnesses << ", have " << mdr->more()->witnessed << dendl;
5633
5658
 
5634
5659
 
5644
5669
    dout(10) << " will remote_wrlock srcdir scatterlocks on mds." << srcdirauth << dendl;
5645
5670
    remote_wrlocks[&srcdn->get_dir()->inode->filelock] = srcdirauth;
5646
5671
    remote_wrlocks[&srcdn->get_dir()->inode->nestlock] = srcdirauth;
 
5672
    if (srci->is_dir())
 
5673
      rdlocks.insert(&srci->dirfragtreelock);
5647
5674
  } else {
5648
5675
    wrlocks.insert(&srcdn->get_dir()->inode->filelock);
5649
5676
    wrlocks.insert(&srcdn->get_dir()->inode->nestlock);
5675
5702
    // open_remote_ino() with 'want_locked=true' when the srcdn or destdn
5676
5703
    // is traversed.
5677
5704
    if (srcdnl->is_remote())
5678
 
      xlocks.insert(&srci->get_parent_dn()->lock);
 
5705
      xlocks.insert(&srci->get_projected_parent_dn()->lock);
5679
5706
    if (destdnl->is_remote())
5680
 
      xlocks.insert(&oldin->get_parent_dn()->lock);
 
5707
      xlocks.insert(&oldin->get_projected_parent_dn()->lock);
5681
5708
  }
5682
5709
 
5683
5710
  // we need to update srci's ctime.  xlock its least contended lock to do that...
5878
5905
  _rename_apply(mdr, srcdn, destdn, straydn);
5879
5906
 
5880
5907
  CDentry::linkage_t *destdnl = destdn->get_linkage();
 
5908
  CInode *in = destdnl->get_inode();
 
5909
  bool need_eval = mdr->more()->cap_imports.count(in);
 
5910
 
5881
5911
  // test hack: test slave commit
5882
 
  if (!mdr->more()->slaves.empty() && !destdnl->get_inode()->is_dir())
 
5912
  if (!mdr->more()->slaves.empty() && !in->is_dir())
5883
5913
    assert(g_conf->mds_kill_rename_at != 5);
5884
 
  if (!mdr->more()->slaves.empty() && destdnl->get_inode()->is_dir())
 
5914
  if (!mdr->more()->slaves.empty() && in->is_dir())
5885
5915
    assert(g_conf->mds_kill_rename_at != 6);
5886
5916
  
5887
5917
  // commit anchor updates?
5892
5922
 
5893
5923
  // bump popularity
5894
5924
  mds->balancer->hit_dir(mdr->now, srcdn->get_dir(), META_POP_IWR);
5895
 
  if (destdnl->is_remote() &&
5896
 
      destdnl->get_inode()->is_auth())
5897
 
    mds->balancer->hit_inode(mdr->now, destdnl->get_inode(), META_POP_IWR);
 
5925
  if (destdnl->is_remote() && in->is_auth())
 
5926
    mds->balancer->hit_inode(mdr->now, in, META_POP_IWR);
5898
5927
 
5899
5928
  // did we import srci?  if so, explicitly ack that import that, before we unlock and reply.
5900
5929
 
5903
5932
  // reply
5904
5933
  MClientReply *reply = new MClientReply(mdr->client_request, 0);
5905
5934
  reply_request(mdr, reply);
5906
 
  
 
5935
 
 
5936
  if (need_eval)
 
5937
    mds->locker->eval(in, CEPH_CAP_LOCKS, true);
 
5938
 
5907
5939
  // clean up?
5908
5940
  if (straydn) 
5909
5941
    mdcache->eval_stray(straydn);
6043
6075
  }
6044
6076
 
6045
6077
  bool force_journal_stray = false;
6046
 
  if (oldin && oldin->is_dir() && !straydn->is_auth())
 
6078
  if (oldin && oldin->is_dir() && straydn && !straydn->is_auth())
6047
6079
    force_journal_stray = _need_force_journal(oldin, true);
6048
6080
 
6049
6081
  if (linkmerge)
6681
6713
  dout(10) << "_logged_slave_rename " << *mdr << dendl;
6682
6714
 
6683
6715
  // prepare ack
6684
 
  MMDSSlaveRequest *reply = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
6685
 
                                                 MMDSSlaveRequest::OP_RENAMEPREPACK);
6686
 
  
 
6716
  MMDSSlaveRequest *reply = NULL;
 
6717
  if (!mdr->aborted)
 
6718
    reply= new MMDSSlaveRequest(mdr->reqid, mdr->attempt, MMDSSlaveRequest::OP_RENAMEPREPACK);
 
6719
 
6687
6720
  CDentry::linkage_t *srcdnl = srcdn->get_linkage();
6688
6721
  CDentry::linkage_t *destdnl = destdn->get_linkage();
6689
6722
  //CDentry::linkage_t *straydnl = straydn ? straydn->get_linkage() : 0;
6706
6739
    for (list<CDir*>::iterator p = bounds.begin(); p != bounds.end(); ++p)
6707
6740
      (*p)->state_clear(CDir::STATE_EXPORTBOUND);
6708
6741
 
6709
 
    ::encode(exported_client_map, reply->inode_export);
6710
 
    reply->inode_export.claim_append(inodebl);
6711
 
    reply->inode_export_v = srcdnl->get_inode()->inode.version;
 
6742
    if (reply) {
 
6743
      ::encode(exported_client_map, reply->inode_export);
 
6744
      reply->inode_export.claim_append(inodebl);
 
6745
      reply->inode_export_v = srcdnl->get_inode()->inode.version;
 
6746
    }
6712
6747
 
6713
6748
    // remove mdr auth pin
6714
6749
    mdr->auth_unpin(srcdnl->get_inode());
6725
6760
  
6726
6761
  destdnl = destdn->get_linkage();
6727
6762
 
6728
 
  mds->send_message_mds(reply, mdr->slave_to_mds);
6729
 
  
6730
6763
  // bump popularity
6731
6764
  mds->balancer->hit_dir(mdr->now, srcdn->get_dir(), META_POP_IWR);
6732
6765
  if (destdnl->get_inode() && destdnl->get_inode()->is_auth())
6736
6769
  mdr->slave_request->put();
6737
6770
  mdr->slave_request = 0;
6738
6771
  mdr->straydn = 0;
 
6772
 
 
6773
  if (reply) {
 
6774
    mds->send_message_mds(reply, mdr->slave_to_mds);
 
6775
  } else {
 
6776
    assert(mdr->aborted);
 
6777
    dout(10) << " abort flag set, finishing" << dendl;
 
6778
    mdcache->request_finish(mdr);
 
6779
  }
6739
6780
}
6740
6781
 
6741
6782
void Server::_commit_slave_rename(MDRequest *mdr, int r,
6896
6937
 
6897
6938
  CDentry *srcdn = NULL;
6898
6939
  CDir *srcdir = mds->mdcache->get_dirfrag(rollback.orig_src.dirfrag);
 
6940
  if (!srcdir)
 
6941
    srcdir = mds->mdcache->get_dirfrag(rollback.orig_src.dirfrag.ino, rollback.orig_src.dname);
6899
6942
  if (srcdir) {
6900
6943
    dout(10) << "  srcdir " << *srcdir << dendl;
6901
6944
    srcdn = srcdir->lookup(rollback.orig_src.dname);
6909
6952
 
6910
6953
  CDentry *destdn = NULL;
6911
6954
  CDir *destdir = mds->mdcache->get_dirfrag(rollback.orig_dest.dirfrag);
 
6955
  if (!destdir)
 
6956
    destdir = mds->mdcache->get_dirfrag(rollback.orig_dest.dirfrag.ino, rollback.orig_dest.dname);
6912
6957
  if (destdir) {
6913
6958
    dout(10) << " destdir " << *destdir << dendl;
6914
6959
    destdn = destdir->lookup(rollback.orig_dest.dname);
7023
7068
      ti = target->get_projected_inode();
7024
7069
    if (ti->ctime == rollback.ctime)
7025
7070
      ti->ctime = rollback.orig_dest.old_ctime;
7026
 
    ti->nlink++;
 
7071
    if (MDS_INO_IS_STRAY(rollback.orig_src.dirfrag.ino)) {
 
7072
      if (MDS_INO_IS_STRAY(rollback.orig_dest.dirfrag.ino))
 
7073
        assert(!rollback.orig_dest.ino && !rollback.orig_dest.remote_ino);
 
7074
      else
 
7075
        assert(rollback.orig_dest.remote_ino &&
 
7076
               rollback.orig_dest.remote_ino == rollback.orig_src.ino);
 
7077
    } else
 
7078
      ti->nlink++;
7027
7079
  }
7028
7080
 
7029
7081
  if (srcdn)