// -- lock types --
// see CEPH_LOCK_*
-
-struct MutationImpl;
-typedef boost::intrusive_ptr<MutationImpl> MutationRef;
-
extern "C" {
#include "locks.h"
}
-
#define CAP_ANY 0
#define CAP_LONER 1
#define CAP_XLOCKER 2
-struct LockType {
- int type;
- const sm_t *sm;
+struct MDLockCache;
+struct MDLockCacheItem;
+struct MutationImpl;
+typedef boost::intrusive_ptr<MutationImpl> MutationRef;
+struct LockType {
explicit LockType(int t) : type(t) {
switch (type) {
case CEPH_LOCK_DN:
}
}
+ int type;
+ const sm_t *sm;
};
class SimpleLock {
public:
- LockType *type;
-
+ // waiting
+ static const uint64_t WAIT_RD = (1<<0); // to read
+ static const uint64_t WAIT_WR = (1<<1); // to write
+ static const uint64_t WAIT_XLOCK = (1<<2); // to xlock (** dup)
+ static const uint64_t WAIT_STABLE = (1<<2); // for a stable state
+ static const uint64_t WAIT_REMOTEXLOCK = (1<<3); // for a remote xlock
+ static const int WAIT_BITS = 4;
+ static const uint64_t WAIT_ALL = ((1<<WAIT_BITS)-1);
+
static std::string_view get_state_name(int n) {
switch (n) {
case LOCK_UNDEF: return "UNDEF";
case CEPH_LOCK_INEST: return "inest";
case CEPH_LOCK_IXATTR: return "ixattr";
case CEPH_LOCK_ISNAP: return "isnap";
- case CEPH_LOCK_INO: return "ino";
case CEPH_LOCK_IFLOCK: return "iflock";
case CEPH_LOCK_IPOLICY: return "ipolicy";
- default: ceph_abort(); return std::string_view();
+ default: return "unknown";
}
}
}
}
- // waiting
- static const uint64_t WAIT_RD = (1<<0); // to read
- static const uint64_t WAIT_WR = (1<<1); // to write
- static const uint64_t WAIT_XLOCK = (1<<2); // to xlock (** dup)
- static const uint64_t WAIT_STABLE = (1<<2); // for a stable state
- static const uint64_t WAIT_REMOTEXLOCK = (1<<3); // for a remote xlock
- static const int WAIT_BITS = 4;
- static const uint64_t WAIT_ALL = ((1<<WAIT_BITS)-1);
-
-
-protected:
- // parent (what i lock)
- MDSCacheObject *parent;
-
- // lock state
- __s16 state;
- __s16 state_flags;
-
- enum {
- LEASED = 1 << 0,
- NEED_RECOVER = 1 << 1,
- };
-
-private:
- int num_rdlock;
-
- // XXX not in mempool
- struct unstable_bits_t {
- set<__s32> gather_set; // auth+rep. >= 0 is mds, < 0 is client
-
- // local state
- int num_wrlock = 0, num_xlock = 0;
- MutationRef xlock_by;
- client_t xlock_by_client = -1;
- client_t excl_client = -1;
-
- bool empty() {
- return
- gather_set.empty() &&
- num_wrlock == 0 &&
- num_xlock == 0 &&
- xlock_by.get() == NULL &&
- xlock_by_client == -1 &&
- excl_client == -1;
- }
-
- unstable_bits_t() {}
- };
-
- mutable std::unique_ptr<unstable_bits_t> _unstable;
-
- bool have_more() const { return _unstable ? true : false; }
- unstable_bits_t *more() const {
- if (!_unstable)
- _unstable.reset(new unstable_bits_t);
- return _unstable.get();
- }
- void try_clear_more() {
- if (_unstable && _unstable->empty()) {
- _unstable.reset();
- }
- }
-
-public:
+ SimpleLock(MDSCacheObject *o, LockType *lt) :
+ type(lt),
+ parent(o)
+ {}
+ virtual ~SimpleLock() {}
client_t get_excl_client() const {
return have_more() ? more()->excl_client : -1;
more()->excl_client = c;
}
- SimpleLock(MDSCacheObject *o, LockType *lt) :
- type(lt),
- parent(o),
- state(LOCK_SYNC),
- state_flags(0),
- num_rdlock(0)
- {}
- virtual ~SimpleLock() {}
-
virtual bool is_scatterlock() const {
return false;
}
int get_type() const { return type->type; }
const sm_t* get_sm() const { return type->sm; }
- int get_wait_shift() const {
- switch (get_type()) {
- case CEPH_LOCK_DN: return 8;
- case CEPH_LOCK_DVERSION: return 8 + 1*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IAUTH: return 8 + 2*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_ILINK: return 8 + 3*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IDFT: return 8 + 4*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IFILE: return 8 + 5*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IVERSION: return 8 + 6*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IXATTR: return 8 + 7*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_ISNAP: return 8 + 8*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_INEST: return 8 + 9*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IFLOCK: return 8 +10*SimpleLock::WAIT_BITS;
- case CEPH_LOCK_IPOLICY: return 8 +11*SimpleLock::WAIT_BITS;
- default:
- ceph_abort();
- }
- }
-
- int get_cap_shift() const {
- switch (get_type()) {
- case CEPH_LOCK_IAUTH: return CEPH_CAP_SAUTH;
- case CEPH_LOCK_ILINK: return CEPH_CAP_SLINK;
- case CEPH_LOCK_IFILE: return CEPH_CAP_SFILE;
- case CEPH_LOCK_IXATTR: return CEPH_CAP_SXATTR;
- default: return 0;
- }
- }
- int get_cap_mask() const {
- switch (get_type()) {
- case CEPH_LOCK_IFILE: return (1 << CEPH_CAP_FILE_BITS) - 1;
- default: return (1 << CEPH_CAP_SIMPLE_BITS) - 1;
- }
- }
-
- struct ptr_lt {
- bool operator()(const SimpleLock* l, const SimpleLock* r) const {
- // first sort by object type (dn < inode)
- if (!(l->type->type > CEPH_LOCK_DN) && (r->type->type > CEPH_LOCK_DN)) return true;
- if ((l->type->type > CEPH_LOCK_DN) == (r->type->type > CEPH_LOCK_DN)) {
- // then sort by object
- if (l->parent->is_lt(r->parent)) return true;
- if (l->parent == r->parent) {
- // then sort by (inode) lock type
- if (l->type->type < r->type->type) return true;
- }
- }
- return false;
- }
- };
+ int get_wait_shift() const;
+ int get_cap_shift() const;
+ int get_cap_mask() const;
void decode_locked_state(const bufferlist& bl) {
parent->decode_lock_state(type->type, bl);
bool is_waiter_for(uint64_t mask) const {
return parent->is_waiter_for(mask << get_wait_shift());
}
-
-
+
+ bool is_cached() const {
+ return state_flags & CACHED;
+ }
+ void add_cache(MDLockCacheItem& item);
+ void remove_cache(MDLockCacheItem& item);
+ MDLockCache* get_first_cache();
// state
int get_state() const { return state; }
return get_sm()->states[state].next;
}
-
bool is_sync_and_unlocked() const {
return
get_state() == LOCK_SYNC &&
!is_xlocked();
}
-
/*
bool fw_rdlock_to_auth() {
return get_sm()->states[state].can_rdlock == FW;
more()->gather_set.erase(i);
}
-
-
virtual bool is_dirty() const { return false; }
virtual bool is_stale() const { return false; }
virtual bool is_flushing() const { return false; }
set_state_rejoin(s, waiters, survivor);
}
-
// caps
bool is_loner_mode() const {
return get_sm()->states[state].loner;
return 0;
}
-
int gcaps_xlocker_mask(client_t client) const {
if (client == get_xlock_by_client())
return type->type == CEPH_LOCK_IFILE ? 0xf : (CEPH_CAP_GSHARED|CEPH_CAP_GEXCL);
_print(out);
out << ")";
}
+
+ LockType *type;
+
+protected:
+ // parent (what i lock)
+ MDSCacheObject *parent;
+
+ // lock state
+ __s16 state = LOCK_SYNC;
+ __s16 state_flags = 0;
+
+ enum {
+ LEASED = 1 << 0,
+ NEED_RECOVER = 1 << 1,
+ CACHED = 1 << 2,
+ };
+
+private:
+ // XXX not in mempool
+ struct unstable_bits_t {
+ unstable_bits_t();
+
+ bool empty() {
+ return
+ gather_set.empty() &&
+ num_wrlock == 0 &&
+ num_xlock == 0 &&
+ xlock_by.get() == NULL &&
+ xlock_by_client == -1 &&
+ excl_client == -1 &&
+ lock_caches.empty();
+ }
+
+ set<__s32> gather_set; // auth+rep. >= 0 is mds, < 0 is client
+
+ // local state
+ int num_wrlock = 0, num_xlock = 0;
+ MutationRef xlock_by;
+ client_t xlock_by_client = -1;
+ client_t excl_client = -1;
+
+ elist<MDLockCacheItem*> lock_caches;
+ };
+
+ bool have_more() const { return _unstable ? true : false; }
+ unstable_bits_t *more() const {
+ if (!_unstable)
+ _unstable.reset(new unstable_bits_t);
+ return _unstable.get();
+ }
+ void try_clear_more() {
+ if (_unstable && _unstable->empty()) {
+ _unstable.reset();
+ }
+ }
+
+ int num_rdlock = 0;
+
+ mutable std::unique_ptr<unstable_bits_t> _unstable;
};
WRITE_CLASS_ENCODER(SimpleLock)
l.print(out);
return out;
}
-
-
#endif