volume: cache volume attr results with vnetroot

moved the FileSystemName definition back down to the kernel, so the daemon is no longer responsible for setting it.  the driver uses the string length to calculate the buffer size needed for NFS41_V_NET_ROOT_EXTENSION.FsAttrs, and copies in the FileSystemName after the first successful volume attributes upcall

Signed-off-by: Casey Bodley <cbodley@umich.edu>
This commit is contained in:
Casey Bodley 2010-10-12 09:51:06 -04:00
parent 25ef4d25bb
commit 827a1b7368
4 changed files with 49 additions and 29 deletions

View file

@ -41,10 +41,6 @@
#define UPCALL_BUF_SIZE 1024
/* FileSystemName reported for FileFsAttributeInformation */
#define NFS41_FILESYSTEM_NAME L"NFS"
#define NFS41_FILESYSTEM_NAME_LEN (sizeof(NFS41_FILESYSTEM_NAME)-sizeof(WCHAR))
/* MaximumComponentNameLength reported for FileFsAttributeInformation */
#define NFS41_MAX_COMPONENT_LEN 64
#define NFS41_MAX_PATH_LEN MAX_PATH

View file

@ -141,12 +141,6 @@ typedef struct __volume_upcall_args {
FILE_FS_SIZE_INFORMATION size;
FILE_FS_FULL_SIZE_INFORMATION fullsize;
FILE_FS_ATTRIBUTE_INFORMATION attribute;
/* attribute.FileSystemName is WCHAR[1], so even though there's
* some extra space in the union from other members, reserve
* enough space for an arbitrary NFS41_FILESYSTEM_NAME_LEN */
unsigned char buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) +
NFS41_FILESYSTEM_NAME_LEN];
} info;
} volume_upcall_args;

View file

@ -98,7 +98,6 @@ static int handle_volume_attributes(
bitmap4 attr_request = { 1, { FATTR4_WORD0_CASE_INSENSITIVE |
FATTR4_WORD0_CASE_PRESERVING } };
PFILE_FS_ATTRIBUTE_INFORMATION attr = &args->info.attribute;
size_t max_length;
int status = NO_ERROR;
status = nfs41_getattr(session, NULL, &attr_request, &info);
@ -117,27 +116,14 @@ static int handle_volume_attributes(
attr->MaximumComponentNameLength = NFS41_MAX_COMPONENT_LEN;
/* calculate how much space we have for FileSystemName; args.info.buffer
* should guarantee us enough room for NFS41_FILESYSTEM_NAME */
max_length = sizeof(args->info) -
FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName);
/* let the driver fill in FileSystemName/Len */
if (FAILED(StringCbCopyNW(attr->FileSystemName, max_length,
NFS41_FILESYSTEM_NAME, NFS41_FILESYSTEM_NAME_LEN))) {
status = ERROR_BUFFER_OVERFLOW;
eprintf("FileSystemName '%S' truncated to '%S'! returning %d\n",
NFS41_FILESYSTEM_NAME, attr->FileSystemName, status);
goto out;
}
attr->FileSystemNameLength = NFS41_FILESYSTEM_NAME_LEN;
args->len = sizeof(args->info.attribute) + NFS41_FILESYSTEM_NAME_LEN;
args->len = sizeof(args->info.attribute);
dprintf(2, "FileFsAttributeInformation: case_preserving %u, "
"case_insensitive %u, max component %u, name '%S', length %u\n",
"case_insensitive %u, max component %u\n",
info.case_preserving, info.case_insensitive,
attr->MaximumComponentNameLength,
attr->FileSystemName, attr->FileSystemNameLength);
attr->MaximumComponentNameLength);
out:
return status;
}

View file

@ -278,10 +278,17 @@ typedef struct _NFS41_NETROOT_EXTENSION {
#define NFS41GetNetRootExtension(pNetRoot) \
(((pNetRoot) == NULL) ? NULL : (PNFS41_NETROOT_EXTENSION)((pNetRoot)->Context))
/* FileSystemName as reported by FileFsAttributeInfo query */
#define FS_NAME L"NFS"
#define FS_NAME_LEN (sizeof(FS_NAME) - sizeof(WCHAR))
#define FS_ATTR_LEN (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + FS_NAME_LEN)
typedef struct _NFS41_V_NET_ROOT_EXTENSION {
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
HANDLE session;
BYTE FsAttrs[FS_ATTR_LEN];
LONG FsAttrsLen;
} NFS41_V_NET_ROOT_EXTENSION, *PNFS41_V_NET_ROOT_EXTENSION;
#define NFS41GetVNetRootExtension(pVNetRoot) \
(((pVNetRoot) == NULL) ? NULL : \
@ -3039,8 +3046,23 @@ NTSTATUS nfs41_QueryVolumeInformation (
goto out;
}
case FileFsSizeInformation:
case FileFsAttributeInformation:
/* used cached fs attributes if available */
if (pVNetRootContext->FsAttrsLen) {
const LONG len = pVNetRootContext->FsAttrsLen;
if (RxContext->Info.LengthRemaining < len) {
RxContext->InformationToReturn = len;
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
RtlCopyMemory(RxContext->Info.Buffer,
pVNetRootContext->FsAttrs, len);
RxContext->Info.LengthRemaining -= len;
status = STATUS_SUCCESS;
goto out;
}
/* else fall through and send the upcall */
case FileFsSizeInformation:
case FileFsFullSizeInformation:
break;
@ -3067,6 +3089,28 @@ NTSTATUS nfs41_QueryVolumeInformation (
RxContext->InformationToReturn = entry->u.Volume.buf_len;
status = STATUS_BUFFER_TOO_SMALL;
} else if (entry->status == STATUS_SUCCESS) {
if (InfoClass == FileFsAttributeInformation) {
/* fill in the FileSystemName */
PFILE_FS_ATTRIBUTE_INFORMATION attrs =
(PFILE_FS_ATTRIBUTE_INFORMATION)RxContext->Info.Buffer;
DECLARE_CONST_UNICODE_STRING(FsName, FS_NAME);
entry->u.Volume.buf_len += FsName.Length;
if (entry->u.Volume.buf_len > RxContext->Info.LengthRemaining) {
RxContext->InformationToReturn = entry->u.Volume.buf_len;
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
RtlCopyMemory(attrs->FileSystemName, FsName.Buffer,
FsName.MaximumLength); /* 'MaximumLength' to include null */
attrs->FileSystemNameLength = FsName.Length;
/* save fs attributes with the vnetroot */
if (entry->u.Volume.buf_len <= FS_ATTR_LEN) {
RtlCopyMemory(&pVNetRootContext->FsAttrs,
RxContext->Info.Buffer, entry->u.Volume.buf_len);
pVNetRootContext->FsAttrsLen = entry->u.Volume.buf_len;
}
}
RxContext->Info.LengthRemaining -= entry->u.Volume.buf_len;
status = STATUS_SUCCESS;
} else {