/** * lock a file on disk for the process. * * @param[in] lf the struct VLockFile representing the file to lock * @param[in] offset the offset in the file to lock * @param[in] locktype READ_LOCK or WRITE_LOCK * @param[in] nonblock 0 to wait for conflicting locks to clear before * obtaining the lock; 1 to fail immediately if a * conflicting lock is held by someone else * * @return operation status * @retval 0 success * @retval EBUSY someone else is holding a conflicting lock and nonblock=1 was * specified * @retval EIO error acquiring file lock * * @note DAFS only * * @note do not try to lock/unlock the same offset in the same file from * different threads; use VGetDiskLock to protect threads from each other in * addition to other processes */ int VLockFileLock(struct VLockFile *lf, afs_uint32 offset, int locktype, int nonblock) { int code; assert(locktype == READ_LOCK || locktype == WRITE_LOCK); AFS_LF_LOCK(lf); if (lf->fd == INVALID_FD) { lf->fd = _VOpenPath(lf->path); if (lf->fd == INVALID_FD) { AFS_LF_UNLOCK(lf); return EIO; } } lf->refcount++; AFS_LF_UNLOCK(lf); code = _VLockFd(lf->fd, offset, locktype, nonblock); if (code) { AFS_LF_LOCK(lf); if (--lf->refcount < 1) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } AFS_LF_UNLOCK(lf); } return code; }
/** * lock a file on disk for the process. * * @param[in] lf the struct VLockFile representing the file to lock * @param[in] offset the offset in the file to lock * @param[in] locktype READ_LOCK or WRITE_LOCK * @param[in] nonblock 0 to wait for conflicting locks to clear before * obtaining the lock; 1 to fail immediately if a * conflicting lock is held by someone else * * @return operation status * @retval 0 success * @retval EBUSY someone else is holding a conflicting lock and nonblock=1 was * specified * @retval EIO error acquiring file lock * * @note DAFS only * * @note do not try to lock/unlock the same offset in the same file from * different threads; use VGetDiskLock to protect threads from each other in * addition to other processes */ int VLockFileLock(struct VLockFile *lf, afs_uint32 offset, int locktype, int nonblock) { int code; opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK); opr_mutex_enter(&lf->mutex); if (lf->fd == INVALID_FD) { lf->fd = _VOpenPath(lf->path); if (lf->fd == INVALID_FD) { opr_mutex_exit(&lf->mutex); return EIO; } } lf->refcount++; opr_mutex_exit(&lf->mutex); code = _VLockFd(lf->fd, offset, locktype, nonblock); if (code) { opr_mutex_enter(&lf->mutex); if (--lf->refcount < 1) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } opr_mutex_exit(&lf->mutex); } return code; }
/** * reinitialize a struct VLockFile. * * Use this to close the lock file (unlocking any locks in it), and effectively * restore lf to the state it was in when it was initialized. This is the same * as unlocking all of the locks on the file, without having to remember what * all of the locks were. Do not unlock previously held locks after calling * this. * * @param[in] lf struct VLockFile to reinit * * @pre nobody is waiting for a lock on this lockfile or otherwise using * this lockfile at all */ void VLockFileReinit(struct VLockFile *lf) { opr_mutex_enter(&lf->mutex); if (lf->fd != INVALID_FD) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } lf->refcount = 0; opr_mutex_exit(&lf->mutex); }
/** * reinitialize a struct VLockFile. * * Use this to close the lock file (unlocking any locks in it), and effectively * restore lf to the state it was in when it was initialized. This is the same * as unlocking all of the locks on the file, without having to remember what * all of the locks were. Do not unlock previously held locks after calling * this. * * @param[in] lf struct VLockFile to reinit * * @pre nobody is waiting for a lock on this lockfile or otherwise using * this lockfile at all */ void VLockFileReinit(struct VLockFile *lf) { MUTEX_ENTER(&lf->mutex); if (lf->fd != INVALID_FD) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } lf->refcount = 0; MUTEX_EXIT(&lf->mutex); }
void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset) { opr_mutex_enter(&lf->mutex); opr_Assert(lf->fd != INVALID_FD); if (--lf->refcount < 1) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } else { _VUnlockFd(lf->fd, offset); } opr_mutex_exit(&lf->mutex); }
void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset) { MUTEX_ENTER(&lf->mutex); osi_Assert(lf->fd != INVALID_FD); if (--lf->refcount < 1) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } else { _VUnlockFd(lf->fd, offset); } MUTEX_EXIT(&lf->mutex); }
void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset) { AFS_LF_LOCK(lf); assert(lf->fd != INVALID_FD); if (--lf->refcount < 1) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } else { _VUnlockFd(lf->fd, offset); } AFS_LF_UNLOCK(lf); }
/** * reinitialize a struct VLockFile. * * Use this to close the lock file (unlocking any locks in it), and effectively * restore lf to the state it was in when it was initialized. This is the same * as unlocking all of the locks on the file, without having to remember what * all of the locks were. Do not unlock previously held locks after calling * this. * * @param[in] lf struct VLockFile to reinit * * @pre nobody is waiting for a lock on this lockfile or otherwise using * this lockfile at all */ void VLockFileReinit(struct VLockFile *lf) { #ifdef AFS_PTHREAD_ENV assert(pthread_mutex_lock(&lf->mutex) == 0); #endif /* AFS_PTHREAD_ENV */ if (lf->fd != INVALID_FD) { _VCloseFd(lf->fd); lf->fd = INVALID_FD; } lf->refcount = 0; #ifdef AFS_PTHREAD_ENV assert(pthread_mutex_unlock(&lf->mutex) == 0); #endif /* AFS_PTHREAD_ENV */ }