<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <errno.h>

#include "common/debug.h"
#include "mdstypes.h"
#include "mds/flock.h"

bool ceph_lock_state_t::is_waiting(ceph_filelock &fl)
{
  multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
  while (p != waiting_locks.end()) {
    if (p->second.start > fl.start)
      return false;
    if (p->second.length == fl.length &&
        p->second.client == fl.client &&
        p->second.pid == fl.pid &&
        p->second.pid_namespace == fl.pid_namespace)
      return true;
    ++p;
  }
  return false;
}

void ceph_lock_state_t::remove_waiting(ceph_filelock& fl)
{
  multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
  while (p != waiting_locks.end()) {
    if (p->second.start > fl.start)
      return;
    if (p->second.length == fl.length &&
        p->second.client == fl.client &&
        p->second.pid == fl.pid &&
        p->second.pid_namespace == fl.pid_namespace) {
      waiting_locks.erase(p);
      return;
    }
    ++p;
  }
}

bool ceph_lock_state_t::add_lock(ceph_filelock& new_lock,
                                 bool wait_on_fail, bool replay)
{
  dout(15) << "add_lock " << new_lock << dendl;
  bool ret = false;
  list<multimap<uint64_t, ceph_filelock>::iterator>
    overlapping_locks, self_overlapping_locks, neighbor_locks;

  // first, get any overlapping locks and split them into owned-by-us and not
  if (get_overlapping_locks(new_lock, overlapping_locks, &neighbor_locks)) {
    dout(15) << "got overlapping lock, splitting by owner" << dendl;
    split_by_owner(new_lock, overlapping_locks, self_overlapping_locks);
  }
  if (!overlapping_locks.empty()) { //overlapping locks owned by others :(
    if (CEPH_LOCK_EXCL == new_lock.type) {
      //can't set, we want an exclusive
      dout(15) << "overlapping lock, and this lock is exclusive, can't set"
              << dendl;
      if (wait_on_fail && !replay) {
        waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
      }
    } else { //shared lock, check for any exclusive locks blocking us
      if (contains_exclusive_lock(overlapping_locks)) { //blocked :(
        dout(15) << " blocked by exclusive lock in overlapping_locks" << dendl;
        if (wait_on_fail && !replay) {
          waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
        }
      } else {
        //yay, we can insert a shared lock
        dout(15) << "inserting shared lock" << dendl;
        adjust_locks(self_overlapping_locks, new_lock, neighbor_locks);
        held_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
        ret = true;
      }
    }
  } else { //no overlapping locks except our own
    adjust_locks(self_overlapping_locks, new_lock, neighbor_locks);
    dout(15) << "no conflicts, inserting " << new_lock << dendl;
    held_locks.insert(pair<uint64_t, ceph_filelock>
                      (new_lock.start, new_lock));
    ret = true;
  }
  if (ret)
    ++client_held_lock_counts[(client_t)new_lock.client];
  else if (wait_on_fail && !replay)
    ++client_waiting_lock_counts[(client_t)new_lock.client];
  return ret;
}

void ceph_lock_state_t::look_for_lock(ceph_filelock& testing_lock)
{
  list<multimap<uint64_t, ceph_filelock>::iterator> overlapping_locks,
    self_overlapping_locks;
  if (get_overlapping_locks(testing_lock, overlapping_locks)) {
    split_by_owner(testing_lock, overlapping_locks, self_overlapping_locks);
  }
  if (!overlapping_locks.empty()) { //somebody else owns overlapping lock
    if (CEPH_LOCK_EXCL == testing_lock.type) { //any lock blocks it
      testing_lock = (*overlapping_locks.begin())->second;
    } else {
      ceph_filelock *blocking_lock;
      if ((blocking_lock = contains_exclusive_lock(overlapping_locks))) {
        testing_lock = *blocking_lock;
      } else { //nothing blocking!
        testing_lock.type = CEPH_LOCK_UNLOCK;
      }<commit_msg>flock: clean up waiting records of a lock when adding it succeeds<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <errno.h>

#include "common/debug.h"
#include "mdstypes.h"
#include "mds/flock.h"

bool ceph_lock_state_t::is_waiting(ceph_filelock &fl)
{
  multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
  while (p != waiting_locks.end()) {
    if (p->second.start > fl.start)
      return false;
    if (p->second.length == fl.length &&
        p->second.client == fl.client &&
        p->second.pid == fl.pid &&
        p->second.pid_namespace == fl.pid_namespace)
      return true;
    ++p;
  }
  return false;
}

void ceph_lock_state_t::remove_waiting(ceph_filelock& fl)
{
  multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
  while (p != waiting_locks.end()) {
    if (p->second.start > fl.start)
      return;
    if (p->second.length == fl.length &&
        p->second.client == fl.client &&
        p->second.pid == fl.pid &&
        p->second.pid_namespace == fl.pid_namespace) {
      waiting_locks.erase(p);
      --client_waiting_lock_counts[(client_t)fl.client];
      if (!client_waiting_lock_counts[(client_t)fl.client]) {
        client_waiting_lock_counts.erase((client_t)fl.client);
      }
      return;
    }
    ++p;
  }
}

bool ceph_lock_state_t::add_lock(ceph_filelock& new_lock,
                                 bool wait_on_fail, bool replay)
{
  dout(15) << "add_lock " << new_lock << dendl;
  bool ret = false;
  list<multimap<uint64_t, ceph_filelock>::iterator>
    overlapping_locks, self_overlapping_locks, neighbor_locks;

  // first, get any overlapping locks and split them into owned-by-us and not
  if (get_overlapping_locks(new_lock, overlapping_locks, &neighbor_locks)) {
    dout(15) << "got overlapping lock, splitting by owner" << dendl;
    split_by_owner(new_lock, overlapping_locks, self_overlapping_locks);
  }
  if (!overlapping_locks.empty()) { //overlapping locks owned by others :(
    if (CEPH_LOCK_EXCL == new_lock.type) {
      //can't set, we want an exclusive
      dout(15) << "overlapping lock, and this lock is exclusive, can't set"
              << dendl;
      if (wait_on_fail && !replay) {
        waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
      }
    } else { //shared lock, check for any exclusive locks blocking us
      if (contains_exclusive_lock(overlapping_locks)) { //blocked :(
        dout(15) << " blocked by exclusive lock in overlapping_locks" << dendl;
        if (wait_on_fail && !replay) {
          waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
        }
      } else {
        //yay, we can insert a shared lock
        dout(15) << "inserting shared lock" << dendl;
        adjust_locks(self_overlapping_locks, new_lock, neighbor_locks);
        held_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
        ret = true;
      }
    }
  } else { //no overlapping locks except our own
    adjust_locks(self_overlapping_locks, new_lock, neighbor_locks);
    dout(15) << "no conflicts, inserting " << new_lock << dendl;
    held_locks.insert(pair<uint64_t, ceph_filelock>
                      (new_lock.start, new_lock));
    ret = true;
  }
  if (ret) {
    ++client_held_lock_counts[(client_t)new_lock.client];
    remove_waiting(new_lock);
  }
  else if (wait_on_fail && !replay)
    ++client_waiting_lock_counts[(client_t)new_lock.client];
  return ret;
}

void ceph_lock_state_t::look_for_lock(ceph_filelock& testing_lock)
{
  list<multimap<uint64_t, ceph_filelock>::iterator> overlapping_locks,
    self_overlapping_locks;
  if (get_overlapping_locks(testing_lock, overlapping_locks)) {
    split_by_owner(testing_lock, overlapping_locks, self_overlapping_locks);
  }
  if (!overlapping_locks.empty()) { //somebody else owns overlapping lock
    if (CEPH_LOCK_EXCL == testing_lock.type) { //any lock blocks it
      testing_lock = (*overlapping_locks.begin())->second;
    } else {
      ceph_filelock *blocking_lock;
      if ((blocking_lock = contains_exclusive_lock(overlapping_locks))) {
        testing_lock = *blocking_lock;
      } else { //nothing blocking!
        testing_lock.type = CEPH_LOCK_UNLOCK;
      }
{'fraction_non_alphanumeric': 0.1282879005260641, 'fraction_numerical': 0.007651841224294596, 'mean_word_length': 3.3864708966963817, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1152622', 'n_tokens_mistral': 3025, 'n_tokens_neox': 2893, 'n_words': 562}