/** * 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; }
/** * 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; }