blob: 7b1e81d58c5daeced5216c9b1f56420f5560a607 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/lib/vfs/cpp/connection/advisory_lock.h"
namespace fs {
namespace internal {
void advisory_lock(zx_koid_t owner, fbl::RefPtr<fs::Vnode> vnode, bool range_ok,
::fuchsia_io::wire::AdvisoryLockRequest& request,
fit::callback<void(zx_status_t status)> callback) {
if (owner == ZX_KOID_INVALID) {
callback(ZX_ERR_INTERNAL);
return;
}
if (!request.has_type()) {
callback(ZX_ERR_INVALID_ARGS);
return;
}
file_lock::LockType lock_type;
switch (request.type()) {
case fuchsia_io::wire::AdvisoryLockType::kRead:
lock_type = file_lock::LockType::READ;
break;
case fuchsia_io::wire::AdvisoryLockType::kWrite:
lock_type = file_lock::LockType::WRITE;
break;
case fuchsia_io::wire::AdvisoryLockType::kUnlock:
lock_type = file_lock::LockType::UNLOCK;
break;
}
// TODO(https://fxbug.dev/42150671) implement range locking
// for F_SETLK, F_SETLKW, and F_GETLK fcntl operations
if (request.has_range()) {
callback(ZX_ERR_NOT_SUPPORTED);
return;
}
auto lock = vnode->GetVnodeFileLock();
if (lock == nullptr) {
callback(ZX_ERR_INTERNAL);
return;
}
bool wait = request.has_wait() && request.wait();
file_lock::LockRequest req(lock_type, wait);
lock->Lock(owner, req, callback);
}
} // namespace internal
} // namespace fs