This repository has been archived by the owner on Jan 20, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LibOS] Implement POSIX locks (fcntl)
Signed-off-by: Paweł Marczewski <[email protected]>
- Loading branch information
Showing
17 changed files
with
1,474 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* SPDX-License-Identifier: LGPL-3.0-or-later */ | ||
/* Copyright (C) 2021 Intel Corporation | ||
* Paweł Marczewski <[email protected]> | ||
*/ | ||
|
||
/* | ||
* File locks. Currently POSIX locks are implemented. | ||
*/ | ||
|
||
#ifndef SHIM_FS_LOCK_H_ | ||
#define SHIM_FS_LOCK_H_ | ||
|
||
|
||
#include <stdbool.h> | ||
|
||
#include "list.h" | ||
#include "shim_types.h" | ||
|
||
#define FS_LOCK_EOF ((uint64_t)-1) | ||
|
||
struct shim_dentry; | ||
|
||
/* Initialize the file locking subsystem. */ | ||
int init_fs_lock(void); | ||
|
||
/* | ||
* POSIX locks (also known as advisory record locks). See `man fcntl` for details. | ||
* | ||
* The current implementation works over IPC and handles all requests in the main process. It has | ||
* the following caveats: | ||
* | ||
* - Lock requests from other processes will always have the overhead of IPC round-trip, even if the | ||
* lock is uncontested. | ||
* - The main process has to be able to look up the same file, so locking will not work for files in | ||
* local-process-only filesystems (tmpfs). | ||
* - There is no deadlock detection (EDEADLK). | ||
* - The lock requests cannot be interrupted (EINTR). | ||
* - The locks work only on files that have a dentry (no pipes, sockets etc.) | ||
*/ | ||
|
||
DEFINE_LISTP(posix_lock); | ||
DEFINE_LIST(posix_lock); | ||
struct posix_lock { | ||
/* Lock type: F_RDLCK, F_WRLCK, F_UNLCK */ | ||
int type; | ||
|
||
/* First byte of range */ | ||
uint64_t start; | ||
|
||
/* Last byte of range (use FS_LOCK_EOF for a range until end of file) */ | ||
uint64_t end; | ||
|
||
/* PID of process taking the lock */ | ||
IDTYPE pid; | ||
|
||
/* List node, used internally */ | ||
LIST_TYPE(posix_lock) list; | ||
}; | ||
|
||
/*! | ||
* \brief Set or remove a lock on a file | ||
* | ||
* \param dent the dentry for a file | ||
* \param pl parameters of new lock | ||
* \param wait if true, will wait until a lock can be taken | ||
* | ||
* This is the equivalent of `fnctl(F_SETLK/F_SETLKW)`. | ||
* | ||
* If `pl->type` is `F_UNLCK`, the function will remove any locks held by the given PID for the | ||
* given range. Removing a locks never waits. | ||
* | ||
* If `pl->type` is `F_RDLCK` or `F_WRLCK`, the function will create a new lock for the given PID | ||
* and range, replacing the existing locks held by the given PID for that range. If there are | ||
* conflicting locks, the function either waits (if `wait` is true), or fails with `-EAGAIN` (if | ||
* `wait` is false). | ||
*/ | ||
int posix_lock_set(struct shim_dentry* dent, struct posix_lock* pl, bool wait); | ||
|
||
/*! | ||
* \brief Check for conflicting locks on a file | ||
* | ||
* \param dent the dentry for a file | ||
* \param pl parameters of new lock (type cannot be `F_UNLCK`) | ||
* \param[out] out_pl on success, set to `F_UNLCK` or details of a conflicting lock | ||
* | ||
* This is the equivalent of `fcntl(F_GETLK)`. | ||
* | ||
* The function checks if there are locks by other PIDs preventing the proposed lock from being | ||
* placed. If the lock could be placed, `out_pl->type` is set to `F_UNLCK`. Otherwise, `out_pl` | ||
* fields (`type`, `start, `end`, `pid`) are set to details of a conflicting lock. | ||
*/ | ||
int posix_lock_get(struct shim_dentry* dent, struct posix_lock* pl, struct posix_lock* out_pl); | ||
|
||
/* Removes all locks for a given PID. Should be called before process exit. */ | ||
int posix_lock_clear_pid(IDTYPE pid); | ||
|
||
/* Version of `posix_lock_set` called from IPC callback. */ | ||
int posix_lock_set_from_ipc(const char* path, struct posix_lock* pl, bool wait, IDTYPE vmid, | ||
unsigned long seq, bool* postponed); | ||
|
||
/* Version of `posix_lock_get` called from IPC callback. */ | ||
int posix_lock_get_from_ipc(const char* path, struct posix_lock* pl, struct posix_lock* out_pl); | ||
|
||
#endif /* SHIM_FS_LOCK_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.