ea: query each superblock for named attr support
adds a new function nfs41_superblock_getattr(), which adds an OPENATTR call with createdir=0 after the GETATTR to check for named attribute support. OPENATTR will either return ERR_NOTSUPP if not supported, or OK/ERR_NOENT depending on whether named attributes are present on the given file. we can't query for the 'named_attr' attribute, because it only tells us whether the given file contains named attributes if named attributes are supported on a superblock, it will return FILE_SUPPORTS_EXTENDED_ATTRIBUTES for associated volume queries Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
fd591f92d7
commit
b3229d20f6
5 changed files with 82 additions and 3 deletions
|
|
@ -49,6 +49,7 @@ typedef struct __nfs41_superblock {
|
||||||
unsigned int cansettime : 1;
|
unsigned int cansettime : 1;
|
||||||
unsigned int link_support : 1;
|
unsigned int link_support : 1;
|
||||||
unsigned int symlink_support : 1;
|
unsigned int symlink_support : 1;
|
||||||
|
unsigned int ea_support : 1;
|
||||||
unsigned int case_preserving : 1;
|
unsigned int case_preserving : 1;
|
||||||
unsigned int case_insensitive : 1;
|
unsigned int case_insensitive : 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1135,6 +1135,72 @@ out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nfs41_superblock_getattr(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN bitmap4 *attr_request,
|
||||||
|
OUT nfs41_file_info *info,
|
||||||
|
OUT bool_t *supports_named_attrs)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
nfs41_compound compound;
|
||||||
|
nfs_argop4 argops[4];
|
||||||
|
nfs_resop4 resops[4];
|
||||||
|
nfs41_sequence_args sequence_args;
|
||||||
|
nfs41_sequence_res sequence_res;
|
||||||
|
nfs41_putfh_args putfh_args;
|
||||||
|
nfs41_putfh_res putfh_res;
|
||||||
|
nfs41_getattr_args getattr_args;
|
||||||
|
nfs41_getattr_res getattr_res;
|
||||||
|
nfs41_openattr_args openattr_args;
|
||||||
|
nfs41_openattr_res openattr_res;
|
||||||
|
|
||||||
|
compound_init(&compound, argops, resops, "getfsattr");
|
||||||
|
|
||||||
|
compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
|
||||||
|
status = nfs41_session_sequence(&sequence_args, session, 0);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
|
||||||
|
putfh_args.file = file;
|
||||||
|
putfh_args.in_recovery = 0;
|
||||||
|
|
||||||
|
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
|
||||||
|
getattr_args.attr_request = attr_request;
|
||||||
|
getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
||||||
|
getattr_res.info = info;
|
||||||
|
|
||||||
|
compound_add_op(&compound, OP_OPENATTR, &openattr_args, &openattr_res);
|
||||||
|
openattr_args.createdir = 0;
|
||||||
|
|
||||||
|
status = compound_encode_send_decode(session, &compound, TRUE);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
status = sequence_res.sr_status;
|
||||||
|
if (status) goto out;
|
||||||
|
status = putfh_res.status;
|
||||||
|
if (status) goto out;
|
||||||
|
status = getattr_res.status;
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
switch (status = openattr_res.status) {
|
||||||
|
case NFS4ERR_NOTSUPP:
|
||||||
|
*supports_named_attrs = 0;
|
||||||
|
status = NFS4_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS4ERR_NOENT:
|
||||||
|
case NFS4_OK:
|
||||||
|
*supports_named_attrs = 1;
|
||||||
|
status = NFS4_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
int nfs41_remove(
|
int nfs41_remove(
|
||||||
IN nfs41_session *session,
|
IN nfs41_session *session,
|
||||||
IN nfs41_path_fh *parent,
|
IN nfs41_path_fh *parent,
|
||||||
|
|
|
||||||
|
|
@ -1129,6 +1129,13 @@ int nfs41_getattr(
|
||||||
IN bitmap4 *attr_request,
|
IN bitmap4 *attr_request,
|
||||||
OUT nfs41_file_info *info);
|
OUT nfs41_file_info *info);
|
||||||
|
|
||||||
|
int nfs41_superblock_getattr(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN bitmap4 *attr_request,
|
||||||
|
OUT nfs41_file_info *info,
|
||||||
|
OUT bool_t *supports_named_attrs);
|
||||||
|
|
||||||
/* getattr.c */
|
/* getattr.c */
|
||||||
int nfs41_cached_getattr(
|
int nfs41_cached_getattr(
|
||||||
IN nfs41_session *session,
|
IN nfs41_session *session,
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ static int get_superblock_attrs(
|
||||||
IN nfs41_superblock *superblock,
|
IN nfs41_superblock *superblock,
|
||||||
IN nfs41_path_fh *file)
|
IN nfs41_path_fh *file)
|
||||||
{
|
{
|
||||||
|
bool_t supports_named_attrs;
|
||||||
int status;
|
int status;
|
||||||
bitmap4 attr_request;
|
bitmap4 attr_request;
|
||||||
nfs41_file_info info = { 0 };
|
nfs41_file_info info = { 0 };
|
||||||
|
|
@ -93,10 +94,11 @@ static int get_superblock_attrs(
|
||||||
info.suppattr_exclcreat = &superblock->suppattr_exclcreat;
|
info.suppattr_exclcreat = &superblock->suppattr_exclcreat;
|
||||||
info.time_delta = &superblock->time_delta;
|
info.time_delta = &superblock->time_delta;
|
||||||
|
|
||||||
status = nfs41_getattr(session, file, &attr_request, &info);
|
status = nfs41_superblock_getattr(session, file,
|
||||||
|
&attr_request, &info, &supports_named_attrs);
|
||||||
if (status) {
|
if (status) {
|
||||||
eprintf("nfs41_getattr() failed with %s when fetching attributes for "
|
eprintf("nfs41_superblock_getattr() failed with %s when fetching "
|
||||||
"fsid(%llu,%llu)\n", nfs_error_string(status),
|
"attributes for fsid(%llu,%llu)\n", nfs_error_string(status),
|
||||||
superblock->fsid.major, superblock->fsid.minor);
|
superblock->fsid.major, superblock->fsid.minor);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +117,7 @@ static int get_superblock_attrs(
|
||||||
superblock->aclsupport = info.aclsupport;
|
superblock->aclsupport = info.aclsupport;
|
||||||
superblock->link_support = info.link_support;
|
superblock->link_support = info.link_support;
|
||||||
superblock->symlink_support = info.symlink_support;
|
superblock->symlink_support = info.symlink_support;
|
||||||
|
superblock->ea_support = supports_named_attrs;
|
||||||
superblock->case_preserving = info.case_preserving;
|
superblock->case_preserving = info.case_preserving;
|
||||||
superblock->case_insensitive = info.case_insensitive;
|
superblock->case_insensitive = info.case_insensitive;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ static void handle_volume_attributes(
|
||||||
attr->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
|
attr->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
|
||||||
if (superblock->symlink_support)
|
if (superblock->symlink_support)
|
||||||
attr->FileSystemAttributes |= FILE_SUPPORTS_REPARSE_POINTS;
|
attr->FileSystemAttributes |= FILE_SUPPORTS_REPARSE_POINTS;
|
||||||
|
if (superblock->ea_support)
|
||||||
|
attr->FileSystemAttributes |= FILE_SUPPORTS_EXTENDED_ATTRIBUTES;
|
||||||
if (superblock->case_preserving)
|
if (superblock->case_preserving)
|
||||||
attr->FileSystemAttributes |= FILE_CASE_PRESERVED_NAMES;
|
attr->FileSystemAttributes |= FILE_CASE_PRESERVED_NAMES;
|
||||||
if (!superblock->case_insensitive)
|
if (!superblock->case_insensitive)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue