|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/pbnLock.h#3 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#ifndef PBN_LOCK_H
|
|
Packit Service |
310c69 |
#define PBN_LOCK_H
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "atomic.h"
|
|
Packit Service |
310c69 |
#include "types.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* The type of a PBN lock.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef enum {
|
|
Packit Service |
310c69 |
VIO_READ_LOCK = 0,
|
|
Packit Service |
310c69 |
VIO_WRITE_LOCK,
|
|
Packit Service |
310c69 |
VIO_COMPRESSED_WRITE_LOCK,
|
|
Packit Service |
310c69 |
VIO_BLOCK_MAP_WRITE_LOCK,
|
|
Packit Service |
310c69 |
} PBNLockType;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef struct pbnLockImplementation PBNLockImplementation;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* A PBN lock.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
struct pbnLock {
|
|
Packit Service |
310c69 |
/** The implementation of the lock */
|
|
Packit Service |
310c69 |
const PBNLockImplementation *implementation;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** The number of VIOs holding or sharing this lock */
|
|
Packit Service |
310c69 |
VIOCount holderCount;
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* The number of compressed block writers holding a share of this lock while
|
|
Packit Service |
310c69 |
* they are acquiring a reference to the PBN.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
uint8_t fragmentLocks;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Whether the locked PBN has been provisionally referenced on behalf of the
|
|
Packit Service |
310c69 |
* lock holder.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
bool hasProvisionalReference;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* For read locks, the number of references that were known to be available
|
|
Packit Service |
310c69 |
* on the locked block at the time the lock was acquired.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
uint8_t incrementLimit;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* For read locks, the number of DataVIOs that have tried to claim one of
|
|
Packit Service |
310c69 |
* the available increments during the lifetime of the lock. Each claim will
|
|
Packit Service |
310c69 |
* first increment this counter, so it can exceed the increment limit.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
Atomic32 incrementsClaimed;
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Initialize a PBNLock.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The lock to initialize
|
|
Packit Service |
310c69 |
* @param type The type of the lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void initializePBNLock(PBNLock *lock, PBNLockType type);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a PBNLock is a read lock.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The lock to check
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the lock is a read lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
bool isPBNReadLock(const PBNLock *lock)
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result));
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Downgrade a PBN write lock to a PBN read lock. The lock holder count is
|
|
Packit Service |
310c69 |
* cleared and the caller is responsible for setting the new count.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The PBN write lock to downgrade
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void downgradePBNWriteLock(PBNLock *lock);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Try to claim one of the available reference count increments on a read
|
|
Packit Service |
310c69 |
* lock. Claims may be attempted from any thread. A claim is only valid until
|
|
Packit Service |
310c69 |
* the PBN lock is released.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The PBN read lock from which to claim an increment
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the claim succeeded, guaranteeing one
|
|
Packit Service |
310c69 |
* increment can be made without overflowing the PBN's reference count
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
bool claimPBNLockIncrement(PBNLock *lock)
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result));
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a PBN lock has a provisional reference.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The PBN lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool hasProvisionalReference(PBNLock *lock)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return ((lock != NULL) && lock->hasProvisionalReference);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Inform a PBN lock that it is responsible for a provisional reference.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The PBN lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void assignProvisionalReference(PBNLock *lock);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Inform a PBN lock that it is no longer responsible for a provisional
|
|
Packit Service |
310c69 |
* reference.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The PBN lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void unassignProvisionalReference(PBNLock *lock);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* If the lock is responsible for a provisional reference, release that
|
|
Packit Service |
310c69 |
* reference. This method is called when the lock is released.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param lock The lock
|
|
Packit Service |
310c69 |
* @param lockedPBN The PBN covered by the lock
|
|
Packit Service |
310c69 |
* @param allocator The block allocator from which to release the reference
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void releaseProvisionalReference(PBNLock *lock,
|
|
Packit Service |
310c69 |
PhysicalBlockNumber lockedPBN,
|
|
Packit Service |
310c69 |
BlockAllocator *allocator);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#endif /* PBN_LOCK_H */
|