cache volume attrs with superblock
This commit is contained in:
parent
a4c726f92d
commit
f80d7ec365
4 changed files with 104 additions and 40 deletions
|
|
@ -39,11 +39,23 @@ typedef struct __nfs41_superblock {
|
|||
nfstime4 time_delta;
|
||||
uint64_t maxread;
|
||||
uint64_t maxwrite;
|
||||
uint32_t layout_types;
|
||||
bool_t cansettime;
|
||||
uint32_t aclsupport;
|
||||
struct list_entry entry; /* position in nfs41_server.superblocks */
|
||||
|
||||
/* constant filesystem attributes */
|
||||
unsigned int layout_types : 3;
|
||||
unsigned int aclsupport : 3;
|
||||
unsigned int cansettime : 1;
|
||||
unsigned int link_support : 1;
|
||||
unsigned int symlink_support : 1;
|
||||
unsigned int case_preserving : 1;
|
||||
unsigned int case_insensitive : 1;
|
||||
|
||||
/* variable filesystem attributes */
|
||||
uint64_t space_avail;
|
||||
uint64_t space_free;
|
||||
uint64_t space_total;
|
||||
time_t cache_expiration; /* applies to space_ attributes */
|
||||
|
||||
SRWLOCK lock;
|
||||
} nfs41_superblock;
|
||||
|
||||
|
|
@ -375,6 +387,9 @@ int nfs41_superblock_for_fh(
|
|||
IN const nfs41_fh *parent OPTIONAL,
|
||||
OUT nfs41_path_fh *file);
|
||||
|
||||
void nfs41_superblock_space_changed(
|
||||
IN nfs41_superblock *superblock);
|
||||
|
||||
void nfs41_superblock_list_init(
|
||||
IN nfs41_superblock_list *superblocks);
|
||||
|
||||
|
|
|
|||
|
|
@ -426,6 +426,9 @@ int nfs41_open(
|
|||
&open_res.resok4.deleg_stateid);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (create == OPEN4_CREATE)
|
||||
nfs41_superblock_space_changed(state->file.fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -607,6 +610,8 @@ int nfs41_create(
|
|||
file->path->path, &file->name, &file->fh,
|
||||
&file_info, &create_res.cinfo);
|
||||
ReleaseSRWLockShared(&file->path->lock);
|
||||
|
||||
nfs41_superblock_space_changed(file->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -749,6 +754,7 @@ int nfs41_write(
|
|||
eprintf("WRITE succeeded with count=0; returning %s\n",
|
||||
nfs_error_string(status));
|
||||
}
|
||||
nfs41_superblock_space_changed(file->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -875,6 +881,7 @@ int nfs41_commit(
|
|||
nfs41_attr_cache_update(session_name_cache(session),
|
||||
file->fh.fileid, &info);
|
||||
}
|
||||
nfs41_superblock_space_changed(file->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1170,6 +1177,8 @@ int nfs41_remove(
|
|||
nfs41_name_cache_remove(session_name_cache(session),
|
||||
parent->path->path, target, &remove_res.cinfo);
|
||||
ReleaseSRWLockShared(&parent->path->lock);
|
||||
|
||||
nfs41_superblock_space_changed(parent->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1322,6 +1331,9 @@ int nfs41_setattr(
|
|||
memcpy(&info->attrmask, &setattr_res.attrsset, sizeof(bitmap4));
|
||||
nfs41_attr_cache_update(session_name_cache(session),
|
||||
file->fh.fileid, info);
|
||||
|
||||
if (setattr_res.attrsset.arr[0] & FATTR4_WORD0_SIZE)
|
||||
nfs41_superblock_space_changed(file->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1430,6 +1442,8 @@ int nfs41_link(
|
|||
dst_dir->path->path, target, &link_out->fh,
|
||||
&info[1], &link_res.cinfo);
|
||||
ReleaseSRWLockShared(&dst_dir->path->lock);
|
||||
|
||||
nfs41_superblock_space_changed(dst_dir->fh.superblock);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,10 @@ static int get_superblock_attrs(
|
|||
nfs41_file_info info;
|
||||
|
||||
attr_request.arr[0] = FATTR4_WORD0_SUPPORTED_ATTRS |
|
||||
FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_MAXREAD |
|
||||
(uint32_t)(FATTR4_WORD0_MAXWRITE) | FATTR4_WORD0_ACLSUPPORT;
|
||||
FATTR4_WORD0_LINK_SUPPORT | FATTR4_WORD0_SYMLINK_SUPPORT |
|
||||
FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME |
|
||||
FATTR4_WORD0_CASE_INSENSITIVE | FATTR4_WORD0_CASE_PRESERVING |
|
||||
FATTR4_WORD0_MAXREAD | (uint32_t)(FATTR4_WORD0_MAXWRITE);
|
||||
attr_request.arr[1] = FATTR4_WORD1_FS_LAYOUT_TYPE |
|
||||
FATTR4_WORD1_TIME_DELTA;
|
||||
attr_request.count = 2;
|
||||
|
|
@ -112,6 +114,11 @@ static int get_superblock_attrs(
|
|||
superblock->maxwrite = session->fore_chan_attrs.ca_maxrequestsize;
|
||||
|
||||
superblock->layout_types = info.fs_layout_types;
|
||||
superblock->aclsupport = info.aclsupport;
|
||||
superblock->link_support = info.link_support;
|
||||
superblock->symlink_support = info.symlink_support;
|
||||
superblock->case_preserving = info.case_preserving;
|
||||
superblock->case_insensitive = info.case_insensitive;
|
||||
|
||||
if (bitmap_isset(&info.attrmask, 0, FATTR4_WORD0_CANSETTIME))
|
||||
superblock->cansettime = info.cansettime;
|
||||
|
|
@ -122,15 +129,18 @@ static int get_superblock_attrs(
|
|||
if (!bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_DELTA))
|
||||
superblock->time_delta.seconds = 1;
|
||||
|
||||
superblock->aclsupport = info.aclsupport;
|
||||
dprintf(SBLVL, "attributes for fsid(%llu,%llu): "
|
||||
"maxread=%llu, maxwrite=%llu, layout_types: 0x%X, "
|
||||
"cansettime=%u, time_delta={%llu,%u}, aclsupport=%d\n",
|
||||
"cansettime=%u, time_delta={%llu,%u}, aclsupport=%u, "
|
||||
"link_support=%u, symlink_support=%u, case_preserving=%u, "
|
||||
"case_insensitive=%u\n",
|
||||
superblock->fsid.major, superblock->fsid.minor,
|
||||
superblock->maxread, superblock->maxwrite,
|
||||
superblock->layout_types, superblock->cansettime,
|
||||
superblock->time_delta.seconds, superblock->time_delta.nseconds,
|
||||
superblock->aclsupport);
|
||||
superblock->aclsupport, superblock->link_support,
|
||||
superblock->symlink_support, superblock->case_preserving,
|
||||
superblock->case_insensitive);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -236,3 +246,12 @@ out:
|
|||
file->fh.superblock, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
void nfs41_superblock_space_changed(
|
||||
IN nfs41_superblock *superblock)
|
||||
{
|
||||
/* invalidate cached volume size attributes */
|
||||
AcquireSRWLockExclusive(&superblock->lock);
|
||||
superblock->cache_expiration = 0;
|
||||
ReleaseSRWLockExclusive(&superblock->lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <Windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "nfs41_ops.h"
|
||||
#include "from_kernel.h"
|
||||
|
|
@ -40,6 +41,8 @@
|
|||
|
||||
#define TO_UNITS(bytes) (bytes / BYTES_PER_UNIT)
|
||||
|
||||
#define VOLUME_CACHE_EXPIRATION 20
|
||||
|
||||
|
||||
/* NFS41_VOLUME_QUERY */
|
||||
static int parse_volume(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||
|
|
@ -63,12 +66,29 @@ static int get_volume_size_info(
|
|||
OUT OPTIONAL PLONGLONG avail_out)
|
||||
{
|
||||
nfs41_file_info info = { 0 };
|
||||
nfs41_superblock *superblock = state->file.fh.superblock;
|
||||
int status = ERROR_NOT_FOUND;
|
||||
|
||||
AcquireSRWLockShared(&superblock->lock);
|
||||
/* check superblock for cached attributes */
|
||||
if (time(NULL) <= superblock->cache_expiration) {
|
||||
info.space_total = superblock->space_total;
|
||||
info.space_avail = superblock->space_avail;
|
||||
info.space_free = superblock->space_free;
|
||||
status = NO_ERROR;
|
||||
|
||||
dprintf(2, "%s cached: %llu user, %llu free of %llu total\n",
|
||||
query, info.space_avail, info.space_free, info.space_total);
|
||||
}
|
||||
ReleaseSRWLockShared(&superblock->lock);
|
||||
|
||||
if (status) {
|
||||
bitmap4 attr_request = { 2, { 0, FATTR4_WORD1_SPACE_AVAIL |
|
||||
FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL } };
|
||||
int status;
|
||||
|
||||
/* query the space_ attributes of the root filesystem */
|
||||
status = nfs41_getattr(state->session, &state->file, &attr_request, &info);
|
||||
/* query the space_ attributes of the filesystem */
|
||||
status = nfs41_getattr(state->session, &state->file,
|
||||
&attr_request, &info);
|
||||
if (status) {
|
||||
eprintf("nfs41_getattr() failed with %s\n",
|
||||
nfs_error_string(status));
|
||||
|
|
@ -76,8 +96,16 @@ static int get_volume_size_info(
|
|||
goto out;
|
||||
}
|
||||
|
||||
dprintf(2, "%s: %llu user, %llu free of %llu total\n", query,
|
||||
info.space_avail, info.space_free, info.space_total);
|
||||
AcquireSRWLockExclusive(&superblock->lock);
|
||||
superblock->space_total = info.space_total;
|
||||
superblock->space_avail = info.space_avail;
|
||||
superblock->space_free = info.space_free;
|
||||
superblock->cache_expiration = time(NULL) + VOLUME_CACHE_EXPIRATION;
|
||||
ReleaseSRWLockExclusive(&superblock->lock);
|
||||
|
||||
dprintf(2, "%s: %llu user, %llu free of %llu total\n",
|
||||
query, info.space_avail, info.space_free, info.space_total);
|
||||
}
|
||||
|
||||
if (total_out) *total_out = TO_UNITS(info.space_total);
|
||||
if (user_out) *user_out = TO_UNITS(info.space_avail);
|
||||
|
|
@ -90,32 +118,20 @@ static int handle_volume_attributes(
|
|||
IN volume_upcall_args *args,
|
||||
IN nfs41_open_state *state)
|
||||
{
|
||||
/* query the case_ attributes of the root filesystem */
|
||||
nfs41_file_info info = { 0 };
|
||||
bitmap4 attr_request = { 1, { FATTR4_WORD0_CASE_INSENSITIVE |
|
||||
FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_SYMLINK_SUPPORT |
|
||||
FATTR4_WORD0_LINK_SUPPORT } };
|
||||
PFILE_FS_ATTRIBUTE_INFORMATION attr = &args->info.attribute;
|
||||
const nfs41_superblock *superblock = state->file.fh.superblock;
|
||||
int status = NO_ERROR;
|
||||
|
||||
status = nfs41_getattr(state->session, &state->file, &attr_request, &info);
|
||||
if (status) {
|
||||
eprintf("nfs41_getattr() failed with %s\n",
|
||||
nfs_error_string(status));
|
||||
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
attr->FileSystemAttributes = FILE_SUPPORTS_REMOTE_STORAGE;
|
||||
if (info.link_support)
|
||||
if (superblock->link_support)
|
||||
attr->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
|
||||
if (info.symlink_support)
|
||||
if (superblock->symlink_support)
|
||||
attr->FileSystemAttributes |= FILE_SUPPORTS_REPARSE_POINTS;
|
||||
if (info.case_preserving)
|
||||
if (superblock->case_preserving)
|
||||
attr->FileSystemAttributes |= FILE_CASE_PRESERVED_NAMES;
|
||||
if (!info.case_insensitive)
|
||||
if (!superblock->case_insensitive)
|
||||
attr->FileSystemAttributes |= FILE_CASE_SENSITIVE_SEARCH;
|
||||
if (state->file.fh.superblock->aclsupport)
|
||||
if (superblock->aclsupport)
|
||||
attr->FileSystemAttributes |= FILE_PERSISTENT_ACLS;
|
||||
|
||||
attr->MaximumComponentNameLength = NFS41_MAX_COMPONENT_LEN;
|
||||
|
|
@ -126,9 +142,9 @@ static int handle_volume_attributes(
|
|||
|
||||
dprintf(2, "FileFsAttributeInformation: case_preserving %u, "
|
||||
"case_insensitive %u, max component %u\n",
|
||||
info.case_preserving, info.case_insensitive,
|
||||
superblock->case_preserving, superblock->case_insensitive,
|
||||
attr->MaximumComponentNameLength);
|
||||
out:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue