volume: daemon handles FileFsAttributeInformation

added FILE_FS_ATTRIBUTE_INFORMATION and FileSystemAttributes flags to from_kernel.h
queries case_preserving, case_insensitive attributes to fill in FileSystemAttributes, and uses #defines from nfs41_const.h for MaximumComponentNameLength and FileSystemName

Signed-off-by: Casey Bodley <cbodley@umich.edu>
This commit is contained in:
Casey Bodley 2010-10-11 16:12:20 -04:00
parent c13ed30b9a
commit d38360672d
6 changed files with 109 additions and 2 deletions

View file

@ -207,6 +207,35 @@ typedef enum _FSINFOCLASS {
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
/* ntifs.h */
#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
#define FILE_CASE_PRESERVED_NAMES 0x00000002
#define FILE_UNICODE_ON_DISK 0x00000004
#define FILE_PERSISTENT_ACLS 0x00000008
#define FILE_FILE_COMPRESSION 0x00000010
#define FILE_VOLUME_QUOTAS 0x00000020
#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
#define FILE_VOLUME_IS_COMPRESSED 0x00008000
#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
#define FILE_SUPPORTS_ENCRYPTION 0x00020000
#define FILE_NAMED_STREAMS 0x00040000
#define FILE_READ_ONLY_VOLUME 0x00080000
#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
#define FILE_SUPPORTS_HARD_LINKS 0x00400000
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
ULONG FileSystemAttributes;
LONG MaximumComponentNameLength;
ULONG FileSystemNameLength;
WCHAR FileSystemName[1];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
/* ntddk.h */
typedef struct _FILE_FS_SIZE_INFORMATION {
LARGE_INTEGER TotalAllocationUnits;

View file

@ -41,8 +41,11 @@
#define UPCALL_BUF_SIZE 1024
/* see MaximumComponentNameLength in FileFsAttributeInformation
* in nfs41_driver.c:nfs41_QueryVolumeInformation() */
/* 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

@ -180,6 +180,8 @@ typedef struct __nfs41_file_info {
uint32_t lease_time; /* XXX: per-server */
uint32_t fs_layout_types; /* pnfs, XXX: per-fs */
bool_t hidden;
bool_t case_insensitive;
bool_t case_preserving;
} nfs41_file_info;
#endif /* !__NFS41_DAEMON_TYPES_H__ */

View file

@ -1546,6 +1546,14 @@ static bool_t decode_file_attrs(
if (!xdr_u_int32_t(xdr, &info->rdattr_error))
return FALSE;
}
if (attrs->attrmask.arr[0] & FATTR4_WORD0_CASE_INSENSITIVE) {
if (!xdr_bool(xdr, &info->case_insensitive))
return FALSE;
}
if (attrs->attrmask.arr[0] & FATTR4_WORD0_CASE_PRESERVING) {
if (!xdr_bool(xdr, &info->case_preserving))
return FALSE;
}
if (attrs->attrmask.arr[0] & FATTR4_WORD0_FILEID) {
if (!xdr_u_hyper(xdr, &info->fileid))
return FALSE;

View file

@ -140,6 +140,13 @@ typedef struct __volume_upcall_args {
union {
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

@ -22,6 +22,7 @@
*/
#include <Windows.h>
#include <strsafe.h>
#include <stdio.h>
#include "nfs41_ops.h"
@ -88,6 +89,59 @@ out:
return status;
}
static int handle_volume_attributes(
IN nfs41_session *session,
IN volume_upcall_args *args)
{
/* 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 } };
PFILE_FS_ATTRIBUTE_INFORMATION attr = &args->info.attribute;
size_t max_length;
int status = NO_ERROR;
status = nfs41_getattr(session, NULL, &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.case_preserving)
attr->FileSystemAttributes |= FILE_CASE_PRESERVED_NAMES;
if (!info.case_insensitive)
attr->FileSystemAttributes |= FILE_CASE_SENSITIVE_SEARCH;
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);
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;
dprintf(2, "FileFsAttributeInformation: case_preserving %u, "
"case_insensitive %u, max component %u, name '%S', length %u\n",
info.case_preserving, info.case_insensitive,
attr->MaximumComponentNameLength,
attr->FileSystemName, attr->FileSystemNameLength);
out:
return status;
}
int handle_volume(nfs41_upcall *upcall)
{
volume_upcall_args *args = &upcall->args.volume;
@ -117,6 +171,10 @@ int handle_volume(nfs41_upcall *upcall)
&args->info.fullsize.ActualAvailableAllocationUnits.QuadPart);
break;
case FileFsAttributeInformation:
status = handle_volume_attributes(session, args);
break;
default:
eprintf("unhandled fs query class %d\n", args->query);
status = ERROR_INVALID_PARAMETER;