quota: split generic quota and nwquota files
All checks were successful
Source release / source-package (push) Successful in 1m4s
All checks were successful
Source release / source-package (push) Successful in 1m4s
This commit is contained in:
16
AI.md
16
AI.md
@@ -2074,12 +2074,24 @@ and all submodules, then rebuild a clean tree before producing new patches.
|
||||
|
||||
Next patch number should be `0271`.
|
||||
|
||||
### 0343 quota file/name split handoff note
|
||||
|
||||
0343 keeps the quota backends deliberately distinguishable. The generic quota
|
||||
frontend helpers live in `include/nwfs/quota.h` and `src/nwfs/quota/quota.c`
|
||||
with `nwfs_quota_*` names only. The NetWare metadata backend lives in
|
||||
`include/nwfs/nwquota.h` and `src/nwfs/quota/nwquota.c` with
|
||||
`nwfs_nwquota_*` public names and `nwfs_nwquota_*` private helpers.
|
||||
|
||||
Do not merge Linux quota and NWQUOTA back into one source file. Future Linux
|
||||
`quotactl()` relocation should get a separate backend implementation while
|
||||
keeping the generic `quota.c` file backend-neutral.
|
||||
|
||||
### 0342 quota relocation handoff note
|
||||
|
||||
0342 starts the planned quota move into `libnwfs`. It moves the
|
||||
metadata/NWQUOTA backend helpers from `src/nwvolume.c` into
|
||||
`src/nwfs/quota/nwfsQuota.c` with public declarations in
|
||||
`include/nwfs/nwfsQuota.h`. `src/nwvolume.c` remains the mars-nwe volume/NCP
|
||||
`src/nwfs/quota/quota.c` and `src/nwfs/quota/nwquota.c` with public declarations in
|
||||
`include/nwfs/quota.h` and `include/nwfs/nwquota.h`. `src/nwvolume.c` remains the mars-nwe volume/NCP
|
||||
entry point and still handles Linux `quotactl()` probing, but now calls libnwfs
|
||||
for NWQUOTA restriction, usage, and adjust operations.
|
||||
|
||||
|
||||
@@ -3207,13 +3207,13 @@ work where project-level headers are added.
|
||||
Third-party imports remain under their own upstream licenses inside the relevant
|
||||
`third_party/` subtree and must be documented separately.
|
||||
|
||||
### Quota backend placement after 0342
|
||||
### Quota backend placement after 0343
|
||||
|
||||
The first quota relocation step moves the metadata/NWQUOTA implementation into
|
||||
The quota relocation keeps the two quota systems deliberately separated inside
|
||||
`libnwfs`:
|
||||
|
||||
- public API: `include/nwfs/nwfsQuota.h`
|
||||
- implementation: `src/nwfs/quota/nwfsQuota.c`
|
||||
- generic quota frontend/API: `include/nwfs/quota.h`, `src/nwfs/quota/quota.c`, `nwfs_quota_*`
|
||||
- NetWare metadata backend/API: `include/nwfs/nwquota.h`, `src/nwfs/quota/nwquota.c`, `nwfs_nwquota_*`
|
||||
- volume-layer callers: `src/nwvolume.c`
|
||||
|
||||
`src/nwvolume.c` remains the NCP/volume entry point and still owns Linux
|
||||
|
||||
15
TODO.md
15
TODO.md
@@ -2323,12 +2323,17 @@ Follow-up:
|
||||
system-collision risk. If yes, give the library, headers, CMake package, and
|
||||
imported tools an `nw` namespace from the first patch.
|
||||
|
||||
### Quota relocation follow-ups after 0342
|
||||
### Quota relocation follow-ups after 0343
|
||||
|
||||
- Re-run `tests/nwfs/nwfs_ncpfs_userquota_dual_smoke.sh` after the 0342
|
||||
structural move. Expected result stays the same as 0340: Linuxquota and
|
||||
metadata/NWQUOTA both deny the next 4K write before data.
|
||||
- Re-run `tests/nwfs/nwfs_ncpfs_userquota_dual_smoke.sh` after the 0343
|
||||
file/function split. Expected result stays the same as 0340/0342:
|
||||
Linuxquota and metadata/NWQUOTA both deny the next 4K write before data.
|
||||
- Keep generic quota helpers in `src/nwfs/quota/quota.c` /
|
||||
`include/nwfs/quota.h` with `nwfs_quota_*` names only.
|
||||
- Keep NetWare metadata quota in `src/nwfs/quota/nwquota.c` /
|
||||
`include/nwfs/nwquota.h` with `nwfs_nwquota_*` names.
|
||||
- Move the remaining Linux `quotactl()` backend out of `src/nwvolume.c` into
|
||||
`src/nwfs/quota/` once 0342 is confirmed green.
|
||||
its own `src/nwfs/quota/` backend file once 0343 is confirmed green; do not
|
||||
merge it into `nwquota.c`.
|
||||
- Keep `src/nwvolume.c` as the stable NCP volume API shim until namespace and
|
||||
quota are both sufficiently represented in `libnwfs`.
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef _NWFS_QUOTA_H_
|
||||
#define _NWFS_QUOTA_H_ 1
|
||||
#ifndef _NWFS_NWQUOTA_H_
|
||||
#define _NWFS_NWQUOTA_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
uint32_t nwfs_quota_blocks_for_size(off_t size);
|
||||
int nwfs_quota_backend_current(void);
|
||||
|
||||
/*
|
||||
* NetWare metadata quota backend. This owns the volume-root
|
||||
* netware.userquota xattr and keeps restriction/usage accounting separate
|
||||
* from Linux kernel quotactl quota.
|
||||
*/
|
||||
int nwfs_nwquota_set_restriction(const char *volume_root, int uid,
|
||||
uint32_t quota4k);
|
||||
int nwfs_nwquota_get_restriction(const char *volume_root, int uid,
|
||||
16
include/nwfs/quota.h
Normal file
16
include/nwfs/quota.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef _NWFS_QUOTA_FRONTEND_H_
|
||||
#define _NWFS_QUOTA_FRONTEND_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* Generic quota helpers shared by quota backends and the mars_nwe volume
|
||||
* layer. Backend-specific APIs live in separate headers such as nwquota.h;
|
||||
* do not add NWQUOTA or Linux quotactl entry points here.
|
||||
*/
|
||||
uint32_t nwfs_quota_blocks_for_size(off_t size);
|
||||
int nwfs_quota_backend_current(void);
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,8 @@ add_library(nwfs SHARED
|
||||
unixNSpace.c
|
||||
longNSpace.c
|
||||
dataStreamNSpace.c
|
||||
quota/nwfsQuota.c)
|
||||
quota/quota.c
|
||||
quota/nwquota.c)
|
||||
add_library(mars_nwe::nwfs ALIAS nwfs)
|
||||
|
||||
set_target_properties(nwfs PROPERTIES
|
||||
@@ -34,7 +35,8 @@ install(TARGETS nwfs
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/zXattr.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/nwfsQuota.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/quota.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/nwquota.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/zasAuthModel.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/nwfs/nameSpaceModel.h"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nwfs")
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/*
|
||||
* NetWare-compatible quota helpers for mars_nwe/libnwfs.
|
||||
* NetWare metadata quota backend for libnwfs.
|
||||
*
|
||||
* This file contains the NWQUOTA metadata backend that stores per-user
|
||||
* restrictions and live usage in the volume-root netware.userquota xattr.
|
||||
* Linux kernel quota probing is still driven by the mars_nwe volume layer;
|
||||
* this file owns the NetWare metadata backend so other nwfs namespace code can
|
||||
* eventually share it as the filesystem compatibility layer grows.
|
||||
* This file owns NWQUOTA accounting: per-user restrictions and live usage are
|
||||
* stored in the volume-root netware.userquota xattr. Keep this backend
|
||||
* separate from the generic quota frontend (quota.c) and from the future Linux
|
||||
* kernel quotactl backend.
|
||||
*/
|
||||
#if defined(__has_include)
|
||||
# if __has_include("config.h")
|
||||
@@ -32,34 +34,23 @@
|
||||
#endif
|
||||
|
||||
#include <nwfs/zXattr.h>
|
||||
#include <nwfs/nwfsQuota.h>
|
||||
#include <nwfs/quota.h>
|
||||
#include <nwfs/nwquota.h>
|
||||
|
||||
uint32_t nwfs_quota_blocks_for_size(off_t size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return(0);
|
||||
return((uint32_t)(((unsigned long long)size + 4095ULL) / 4096ULL));
|
||||
}
|
||||
|
||||
int nwfs_quota_backend_current(void)
|
||||
{
|
||||
return(nwfs_quota_backend_from_string(getenv(NWFS_QUOTA_BACKEND_ENV)));
|
||||
}
|
||||
|
||||
static void nwfs_mars_uid_to_guid(int uid, GUID_t *guid)
|
||||
static void nwfs_nwquota_mars_uid_to_guid(int uid, GUID_t *guid)
|
||||
{
|
||||
memset(guid, 0, sizeof(*guid));
|
||||
guid->timeLow = (LONG)uid;
|
||||
}
|
||||
|
||||
static int nwfs_guid_to_mars_uid(const GUID_t *guid)
|
||||
static int nwfs_nwquota_guid_to_mars_uid(const GUID_t *guid)
|
||||
{
|
||||
return((int)guid->timeLow);
|
||||
}
|
||||
|
||||
#if XATTR_SUPPORT
|
||||
static const char *nwfs_xattr_name(const char *name, char *buffer,
|
||||
size_t buffer_len)
|
||||
static const char *nwfs_nwquota_xattr_name(const char *name, char *buffer,
|
||||
size_t buffer_len)
|
||||
{
|
||||
if (!name || !*name)
|
||||
return(name);
|
||||
@@ -85,12 +76,12 @@ static const char *nwfs_xattr_name(const char *name, char *buffer,
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t nwfs_quota_getxattr(const char *path, const char *name,
|
||||
void *value, size_t size)
|
||||
static ssize_t nwfs_nwquota_getxattr(const char *path, const char *name,
|
||||
void *value, size_t size)
|
||||
{
|
||||
#if XATTR_SUPPORT
|
||||
char xname[256 + 5];
|
||||
return(getxattr(path, nwfs_xattr_name(name, xname, sizeof(xname)),
|
||||
return(getxattr(path, nwfs_nwquota_xattr_name(name, xname, sizeof(xname)),
|
||||
value, size));
|
||||
#else
|
||||
(void)path;
|
||||
@@ -102,12 +93,12 @@ static ssize_t nwfs_quota_getxattr(const char *path, const char *name,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int nwfs_quota_setxattr(const char *path, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
static int nwfs_nwquota_setxattr(const char *path, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
{
|
||||
#if XATTR_SUPPORT
|
||||
char xname[256 + 5];
|
||||
return(setxattr(path, nwfs_xattr_name(name, xname, sizeof(xname)),
|
||||
return(setxattr(path, nwfs_nwquota_xattr_name(name, xname, sizeof(xname)),
|
||||
value, size, flags));
|
||||
#else
|
||||
(void)path;
|
||||
@@ -120,8 +111,8 @@ static int nwfs_quota_setxattr(const char *path, const char *name,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int read_userquota_from_volume(const char *volume_root,
|
||||
zNW_user_quota_s *userquota)
|
||||
static int nwfs_nwquota_read_userquota_from_volume(const char *volume_root,
|
||||
zNW_user_quota_s *userquota)
|
||||
{
|
||||
ssize_t len;
|
||||
int euid;
|
||||
@@ -142,8 +133,8 @@ static int read_userquota_from_volume(const char *volume_root,
|
||||
return(-1);
|
||||
|
||||
memset(userquota, 0, sizeof(*userquota));
|
||||
len = nwfs_quota_getxattr(volume_root, zNW_USERQUOTA, userquota,
|
||||
sizeof(*userquota));
|
||||
len = nwfs_nwquota_getxattr(volume_root, zNW_USERQUOTA, userquota,
|
||||
sizeof(*userquota));
|
||||
if (len < 0) {
|
||||
rc = -1;
|
||||
} else if (nwfs_userquota_validate(userquota, (size_t)len) != NWFS_OK) {
|
||||
@@ -155,8 +146,8 @@ static int read_userquota_from_volume(const char *volume_root,
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static int write_userquota_to_volume(const char *volume_root,
|
||||
zNW_user_quota_s *userquota)
|
||||
static int nwfs_nwquota_write_userquota_to_volume(const char *volume_root,
|
||||
zNW_user_quota_s *userquota)
|
||||
{
|
||||
size_t size;
|
||||
int euid;
|
||||
@@ -173,20 +164,20 @@ static int write_userquota_to_volume(const char *volume_root,
|
||||
if (euid != 0 && seteuid(0))
|
||||
return(-1);
|
||||
|
||||
rc = nwfs_quota_setxattr(volume_root, zNW_USERQUOTA, userquota, size, 0);
|
||||
rc = nwfs_nwquota_setxattr(volume_root, zNW_USERQUOTA, userquota, size, 0);
|
||||
|
||||
if (euid != 0 && seteuid(euid))
|
||||
abort();
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static int nwfs_volume_file_owned_by_quota_user(const struct stat *st, int uid)
|
||||
static int nwfs_nwquota_file_owned_by_quota_user(const struct stat *st, int uid)
|
||||
{
|
||||
return(st && st->st_uid == (uid_t)uid);
|
||||
}
|
||||
|
||||
static uint32_t nwfs_volume_user_usage_4k_scan(const char *path, int uid,
|
||||
dev_t root_dev)
|
||||
static uint32_t nwfs_nwquota_user_usage_4k_scan(const char *path, int uid,
|
||||
dev_t root_dev)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
@@ -197,7 +188,7 @@ static uint32_t nwfs_volume_user_usage_4k_scan(const char *path, int uid,
|
||||
return(0);
|
||||
if (st.st_dev != root_dev)
|
||||
return(0);
|
||||
if (S_ISREG(st.st_mode) && nwfs_volume_file_owned_by_quota_user(&st, uid))
|
||||
if (S_ISREG(st.st_mode) && nwfs_nwquota_file_owned_by_quota_user(&st, uid))
|
||||
return(nwfs_quota_blocks_for_size(st.st_size));
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return(0);
|
||||
@@ -222,13 +213,13 @@ static uint32_t nwfs_volume_user_usage_4k_scan(const char *path, int uid,
|
||||
child[len] = '\0';
|
||||
}
|
||||
strcpy(child + len, de->d_name);
|
||||
blocks += nwfs_volume_user_usage_4k_scan(child, uid, root_dev);
|
||||
blocks += nwfs_nwquota_user_usage_4k_scan(child, uid, root_dev);
|
||||
}
|
||||
closedir(dir);
|
||||
return(blocks);
|
||||
}
|
||||
|
||||
static uint32_t nwfs_volume_user_usage_4k(const char *volume_root, int uid)
|
||||
static uint32_t nwfs_nwquota_user_usage_4k(const char *volume_root, int uid)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@@ -236,11 +227,11 @@ static uint32_t nwfs_volume_user_usage_4k(const char *volume_root, int uid)
|
||||
return(0);
|
||||
if (stat(volume_root, &st) != 0)
|
||||
return(0);
|
||||
return(nwfs_volume_user_usage_4k_scan(volume_root, uid, st.st_dev));
|
||||
return(nwfs_nwquota_user_usage_4k_scan(volume_root, uid, st.st_dev));
|
||||
}
|
||||
|
||||
static uint32_t nwfs_userquota_used_4k(zNW_user_restriction_s *entry,
|
||||
uint32_t scanned)
|
||||
static uint32_t nwfs_nwquota_used_4k(zNW_user_restriction_s *entry,
|
||||
uint32_t scanned)
|
||||
{
|
||||
uint32_t stored;
|
||||
|
||||
@@ -267,13 +258,13 @@ int nwfs_nwquota_set_restriction(const char *volume_root, int uid,
|
||||
uint32_t inuse;
|
||||
int i;
|
||||
|
||||
if (read_userquota_from_volume(volume_root, &userquota))
|
||||
if (nwfs_nwquota_read_userquota_from_volume(volume_root, &userquota))
|
||||
nwfs_userquota_init(&userquota);
|
||||
|
||||
inuse = nwfs_volume_user_usage_4k(volume_root, uid);
|
||||
inuse = nwfs_nwquota_user_usage_4k(volume_root, uid);
|
||||
|
||||
for (i = 0; i < userquota.nwuq_num_users; i++) {
|
||||
if (nwfs_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
if (nwfs_nwquota_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
if (quota4k == 0) {
|
||||
if (i + 1 < userquota.nwuq_num_users) {
|
||||
memmove(&userquota.nwuq_user[i], &userquota.nwuq_user[i + 1],
|
||||
@@ -285,7 +276,7 @@ int nwfs_nwquota_set_restriction(const char *volume_root, int uid,
|
||||
userquota.nwuq_user[i].nwur_restriction = (SQUAD)quota4k;
|
||||
userquota.nwuq_user[i].nwur_reserved_2 = (QUAD)inuse;
|
||||
}
|
||||
return(write_userquota_to_volume(volume_root, &userquota));
|
||||
return(nwfs_nwquota_write_userquota_to_volume(volume_root, &userquota));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,11 +285,12 @@ int nwfs_nwquota_set_restriction(const char *volume_root, int uid,
|
||||
if (userquota.nwuq_num_users >= zMAX_XATTR_USERS)
|
||||
return(-1);
|
||||
|
||||
nwfs_mars_uid_to_guid(uid, &userquota.nwuq_user[userquota.nwuq_num_users].nwur_user);
|
||||
nwfs_nwquota_mars_uid_to_guid(
|
||||
uid, &userquota.nwuq_user[userquota.nwuq_num_users].nwur_user);
|
||||
userquota.nwuq_user[userquota.nwuq_num_users].nwur_restriction = (SQUAD)quota4k;
|
||||
userquota.nwuq_user[userquota.nwuq_num_users].nwur_reserved_2 = (QUAD)inuse;
|
||||
userquota.nwuq_num_users++;
|
||||
return(write_userquota_to_volume(volume_root, &userquota));
|
||||
return(nwfs_nwquota_write_userquota_to_volume(volume_root, &userquota));
|
||||
}
|
||||
|
||||
int nwfs_nwquota_get_restriction(const char *volume_root, int uid,
|
||||
@@ -312,17 +304,17 @@ int nwfs_nwquota_get_restriction(const char *volume_root, int uid,
|
||||
|
||||
*quota4k = 0x40000000;
|
||||
*inuse4k = 0;
|
||||
if (read_userquota_from_volume(volume_root, &userquota))
|
||||
if (nwfs_nwquota_read_userquota_from_volume(volume_root, &userquota))
|
||||
return(0);
|
||||
|
||||
for (i = 0; i < userquota.nwuq_num_users; i++) {
|
||||
if (nwfs_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
uint32_t scanned = nwfs_volume_user_usage_4k(volume_root, uid);
|
||||
if (nwfs_nwquota_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
uint32_t scanned = nwfs_nwquota_user_usage_4k(volume_root, uid);
|
||||
if (userquota.nwuq_user[i].nwur_restriction <= 0)
|
||||
*quota4k = 0x40000000;
|
||||
else
|
||||
*quota4k = (uint32_t)userquota.nwuq_user[i].nwur_restriction;
|
||||
*inuse4k = nwfs_userquota_used_4k(&userquota.nwuq_user[i], scanned);
|
||||
*inuse4k = nwfs_nwquota_used_4k(&userquota.nwuq_user[i], scanned);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
@@ -334,11 +326,11 @@ int nwfs_nwquota_has_restriction(const char *volume_root, int uid)
|
||||
zNW_user_quota_s userquota;
|
||||
int i;
|
||||
|
||||
if (read_userquota_from_volume(volume_root, &userquota))
|
||||
if (nwfs_nwquota_read_userquota_from_volume(volume_root, &userquota))
|
||||
return(0);
|
||||
|
||||
for (i = 0; i < userquota.nwuq_num_users; i++) {
|
||||
if (nwfs_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid)
|
||||
if (nwfs_nwquota_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid)
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
@@ -354,13 +346,13 @@ int nwfs_nwquota_adjust_usage(const char *volume_root, int uid,
|
||||
*used4k = 0;
|
||||
if (delta4k == 0)
|
||||
return(0);
|
||||
if (read_userquota_from_volume(volume_root, &userquota))
|
||||
if (nwfs_nwquota_read_userquota_from_volume(volume_root, &userquota))
|
||||
return(0);
|
||||
|
||||
for (i = 0; i < userquota.nwuq_num_users; i++) {
|
||||
if (nwfs_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
uint32_t scanned = nwfs_volume_user_usage_4k(volume_root, uid);
|
||||
uint32_t used = nwfs_userquota_used_4k(&userquota.nwuq_user[i], scanned);
|
||||
if (nwfs_nwquota_guid_to_mars_uid(&userquota.nwuq_user[i].nwur_user) == uid) {
|
||||
uint32_t scanned = nwfs_nwquota_user_usage_4k(volume_root, uid);
|
||||
uint32_t used = nwfs_nwquota_used_4k(&userquota.nwuq_user[i], scanned);
|
||||
|
||||
if (delta4k < 0) {
|
||||
uint32_t dec = (uint32_t)(-delta4k);
|
||||
@@ -373,7 +365,7 @@ int nwfs_nwquota_adjust_usage(const char *volume_root, int uid,
|
||||
userquota.nwuq_user[i].nwur_reserved_2 = (QUAD)used;
|
||||
if (used4k)
|
||||
*used4k = used;
|
||||
return(write_userquota_to_volume(volume_root, &userquota));
|
||||
return(nwfs_nwquota_write_userquota_to_volume(volume_root, &userquota));
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
32
src/nwfs/quota/quota.c
Normal file
32
src/nwfs/quota/quota.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Generic quota helpers for libnwfs.
|
||||
*
|
||||
* Keep this file backend-neutral. NetWare metadata quota lives in nwquota.c;
|
||||
* Linux kernel quotactl quota should get its own backend file when it moves
|
||||
* from the mars_nwe volume layer.
|
||||
*/
|
||||
#if defined(__has_include)
|
||||
# if __has_include("config.h")
|
||||
# include "config.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <nwfs/zXattr.h>
|
||||
#include <nwfs/quota.h>
|
||||
|
||||
uint32_t nwfs_quota_blocks_for_size(off_t size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return(0);
|
||||
return((uint32_t)(((unsigned long long)size + 4095ULL) / 4096ULL));
|
||||
}
|
||||
|
||||
int nwfs_quota_backend_current(void)
|
||||
{
|
||||
return(nwfs_quota_backend_from_string(getenv(NWFS_QUOTA_BACKEND_ENV)));
|
||||
}
|
||||
@@ -55,7 +55,8 @@
|
||||
#include "unxfile.h"
|
||||
#include "nwxattr.h"
|
||||
#include <nwfs/zXattr.h>
|
||||
#include <nwfs/nwfsQuota.h>
|
||||
#include <nwfs/quota.h>
|
||||
#include <nwfs/nwquota.h>
|
||||
|
||||
#define VOLOPTIONS_DEFAULT VOL_OPTION_ATTRIBUTES
|
||||
|
||||
|
||||
Reference in New Issue
Block a user