return;
}
+ // TODO: maybe other internal requests don't care
+ bool ignore_peer_requests = false
+ || mdr->internal_op == CEPH_MDS_OP_LOCK_PATH
+ ;
+
// rollback peer requests is tricky. just let the request proceed.
- if (mdr->has_more() &&
+ if (!ignore_peer_requests && mdr->has_more() &&
(!mdr->more()->witnessed.empty() || !mdr->more()->waiting_on_peer.empty())) {
if (!(mdr->locking_state & MutationImpl::ALL_LOCKED)) {
ceph_assert(mdr->more()->witnessed.empty());
});
}
mdr->internal_op_private = new LockPathState{std::move(config)};
+ if (config.lifetime) {
+ mds->timer.add_event_after(*config.lifetime, new LambdaContext([this, mdr]() {
+ if (!mdr->result && !mdr->aborted && !mdr->killed && !mdr->dead) {
+ mdr->result = -CEPHFS_ECANCELED;
+ request_kill(mdr);
+ }
+ }));
+ }
dispatch_request(mdr);
return mdr;
}
void add_quiesce(CInode* parent, CInode* in);
struct LockPathConfig {
+ using Lifetime = std::chrono::milliseconds;
filepath fpath;
std::vector<std::string> locks;
+ std::optional<Lifetime> lifetime;
bool ap_dont_block = false;
bool ap_freeze = false;
};
" name=ap_dont_block,type=CephBool,req=false"
" name=ap_freeze,type=CephBool,req=false"
" name=await,type=CephBool,req=false"
+ " name=lifetime,type=CephFloat,req=false"
,asok_hook
,"lock a path");
ceph_assert(r == 0);
config.ap_dont_block = cmd_getval_or<bool>(cmdmap, "ap_dont_block", false);
config.ap_freeze = cmd_getval_or<bool>(cmdmap, "ap_freeze", false);
config.fpath = filepath(path);
+ if (double lifetime; cmd_getval(cmdmap, "lifetime", lifetime)) {
+ using std::chrono::duration_cast;
+ config.lifetime = duration_cast<MDCache::LockPathConfig::Lifetime>(std::chrono::duration<double>(lifetime));
+ }
bool await = cmd_getval_or<bool>(cmdmap, "await", false);
auto respond = [f, on_finish=std::move(on_finish)](MDRequestRef const& req) {