superblock: mask getattr requests with supported_attrs

on creation of a new superblock, construct a bitmap for the default attribute mask to be used for GETATTR and READDIR requests on that filesystem.  mask out any unsupported attributes, and store the bitmap in the field nfs41_superblock.default_getattr

replaced function init_getattr_request() with nfs41_superblock_getattr_mask(), which returns a copy of superblock->default_getattr

removed the locking in nfs41_superblock_supported_attrs() and nfs41_superblock_supported_attrs_exclcreat(), as the supported_attrs and suppattr_exclcreat fields are read-only after the superblock is first initialized.  also factored out their common code into a bitmap_intersect() function in util.h

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2012-04-02 14:22:58 -04:00 committed by unknown
parent b955b6d3fe
commit c59124dd20
9 changed files with 65 additions and 71 deletions

View file

@ -45,7 +45,7 @@ int nfs41_cached_getattr(
if (status) { if (status) {
/* fetch attributes from the server */ /* fetch attributes from the server */
bitmap4 attr_request; bitmap4 attr_request;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
status = nfs41_getattr(session, file, &attr_request, info); status = nfs41_getattr(session, file, &attr_request, info);
if (status) { if (status) {

View file

@ -22,7 +22,7 @@
#ifndef __NFS41__ #ifndef __NFS41__
#define __NFS41__ #define __NFS41__
#include "nfs41_types.h" #include "util.h"
#include "list.h" #include "list.h"
@ -33,12 +33,15 @@ struct __nfs41_root;
typedef struct __nfs41_superblock { typedef struct __nfs41_superblock {
nfs41_fsid fsid; nfs41_fsid fsid;
struct list_entry entry; /* position in nfs41_server.superblocks */
bitmap4 supported_attrs; bitmap4 supported_attrs;
bitmap4 suppattr_exclcreat; bitmap4 suppattr_exclcreat;
bitmap4 default_getattr;
nfstime4 time_delta; nfstime4 time_delta;
uint64_t maxread; uint64_t maxread;
uint64_t maxwrite; uint64_t maxwrite;
struct list_entry entry; /* position in nfs41_server.superblocks */
/* constant filesystem attributes */ /* constant filesystem attributes */
unsigned int layout_types : 3; unsigned int layout_types : 3;
@ -420,13 +423,24 @@ int nfs41_superblock_for_fh(
IN const nfs41_fh *parent OPTIONAL, IN const nfs41_fh *parent OPTIONAL,
OUT nfs41_path_fh *file); OUT nfs41_path_fh *file);
void nfs41_superblock_supported_attrs( static __inline void nfs41_superblock_getattr_mask(
IN nfs41_superblock *superblock, IN const nfs41_superblock *superblock,
IN OUT bitmap4 *attrs); OUT bitmap4 *attrs)
{
void nfs41_superblock_supported_attrs_exclcreat( memcpy(attrs, &superblock->default_getattr, sizeof(bitmap4));
IN nfs41_superblock *superblock, }
IN OUT bitmap4 *attrs); static __inline void nfs41_superblock_supported_attrs(
IN const nfs41_superblock *superblock,
IN OUT bitmap4 *attrs)
{
bitmap_intersect(attrs, &superblock->supported_attrs);
}
static __inline void nfs41_superblock_supported_attrs_exclcreat(
IN const nfs41_superblock *superblock,
IN OUT bitmap4 *attrs)
{
bitmap_intersect(attrs, &superblock->suppattr_exclcreat);
}
void nfs41_superblock_space_changed( void nfs41_superblock_space_changed(
IN nfs41_superblock *superblock); IN nfs41_superblock *superblock);

View file

@ -412,6 +412,7 @@ int nfs41_open(
current_fh_is_dir = TRUE; current_fh_is_dir = TRUE;
/* SEQUENCE; PUTFH(dir); SAVEFH; OPEN; /* SEQUENCE; PUTFH(dir); SAVEFH; OPEN;
* GETFH(file); GETATTR(file); RESTOREFH(dir); GETATTR */ * GETFH(file); GETATTR(file); RESTOREFH(dir); GETATTR */
nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request);
break; break;
case CLAIM_PREVIOUS: case CLAIM_PREVIOUS:
case CLAIM_FH: case CLAIM_FH:
@ -421,13 +422,13 @@ int nfs41_open(
/* CURRENT_FH: file being opened */ /* CURRENT_FH: file being opened */
current_fh_is_dir = FALSE; current_fh_is_dir = FALSE;
/* SEQUENCE; PUTFH(file); OPEN; GETATTR(file); PUTFH(dir); GETATTR */ /* SEQUENCE; PUTFH(file); OPEN; GETATTR(file); PUTFH(dir); GETATTR */
nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
break; break;
} }
if (info == NULL) if (info == NULL)
info = &tmp_info; info = &tmp_info;
init_getattr_request(&attr_request);
attr_request.arr[0] |= FATTR4_WORD0_FSID; attr_request.arr[0] |= FATTR4_WORD0_FSID;
compound_init(&compound, argops, resops, "open"); compound_init(&compound, argops, resops, "open");
@ -556,7 +557,7 @@ int nfs41_create(
nfs41_savefh_res savefh_res; nfs41_savefh_res savefh_res;
nfs41_restorefh_res restorefh_res; nfs41_restorefh_res restorefh_res;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, "create"); compound_init(&compound, argops, resops, "create");
@ -648,7 +649,7 @@ int nfs41_close(
bitmap4 attr_request; bitmap4 attr_request;
nfs41_file_info info; nfs41_file_info info;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, "close"); compound_init(&compound, argops, resops, "close");
@ -713,7 +714,7 @@ int nfs41_write(
bitmap4 attr_request; bitmap4 attr_request;
nfs41_file_info info = { 0 }, *pinfo; nfs41_file_info info = { 0 }, *pinfo;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, compound_init(&compound, argops, resops,
stateid->stateid.seqid == 0 ? "ds write" : "write"); stateid->stateid.seqid == 0 ? "ds write" : "write");
@ -887,7 +888,7 @@ int nfs41_commit(
if (cinfo) pinfo = cinfo; if (cinfo) pinfo = cinfo;
else pinfo = &info; else pinfo = &info;
if (do_getattr) { if (do_getattr) {
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res); compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request; getattr_args.attr_request = &attr_request;
@ -1079,18 +1080,6 @@ out:
return status; return status;
} }
void init_getattr_request(bitmap4 *attr_request)
{
attr_request->count = 2;
attr_request->arr[0] = FATTR4_WORD0_TYPE |
FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE |
FATTR4_WORD0_FILEID | FATTR4_WORD0_HIDDEN | FATTR4_WORD0_ARCHIVE;
attr_request->arr[1] = FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS |
FATTR4_WORD1_SYSTEM | FATTR4_WORD1_TIME_ACCESS |
FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_MODIFY;
attr_request->arr[2] = 0;
}
int nfs41_getattr( int nfs41_getattr(
IN nfs41_session *session, IN nfs41_session *session,
IN OPTIONAL nfs41_path_fh *file, IN OPTIONAL nfs41_path_fh *file,
@ -1167,7 +1156,7 @@ int nfs41_remove(
bitmap4 attr_request; bitmap4 attr_request;
nfs41_file_info info; nfs41_file_info info;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, "remove"); compound_init(&compound, argops, resops, "remove");
@ -1238,7 +1227,7 @@ int nfs41_rename(
bitmap4 attr_request; bitmap4 attr_request;
nfs41_restorefh_res restorefh_res; nfs41_restorefh_res restorefh_res;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(src_dir->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, "rename"); compound_init(&compound, argops, resops, "rename");
@ -1353,7 +1342,7 @@ int nfs41_setattr(
setattr_args.stateid = stateid; setattr_args.stateid = stateid;
setattr_args.info = info; setattr_args.info = info;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res); compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request; getattr_args.attr_request = &attr_request;
getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
@ -1402,8 +1391,8 @@ int nfs41_link(
nfs41_file_info info = { 0 }; nfs41_file_info info = { 0 };
nfs41_path_fh file; nfs41_path_fh file;
init_getattr_request(&info.attrmask); nfs41_superblock_getattr_mask(src->fh.superblock, &info.attrmask);
init_getattr_request(&cinfo->attrmask); nfs41_superblock_getattr_mask(dst_dir->fh.superblock, &cinfo->attrmask);
cinfo->attrmask.arr[0] |= FATTR4_WORD0_FSID; cinfo->attrmask.arr[0] |= FATTR4_WORD0_FSID;
compound_init(&compound, argops, resops, "link"); compound_init(&compound, argops, resops, "link");
@ -2018,7 +2007,7 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
nfs41_getattr_res getattr_res; nfs41_getattr_res getattr_res;
bitmap4 attr_request; bitmap4 attr_request;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
compound_init(&compound, argops, resops, "layoutcommit"); compound_init(&compound, argops, resops, "layoutcommit");

View file

@ -1123,9 +1123,6 @@ int nfs41_readdir(
IN OUT uint32_t *entries_len, IN OUT uint32_t *entries_len,
OUT bool_t *eof_out); OUT bool_t *eof_out);
void init_getattr_request(
OUT bitmap4 *attr_request);
int nfs41_getattr( int nfs41_getattr(
IN nfs41_session *session, IN nfs41_session *session,
IN OPTIONAL nfs41_path_fh *file, IN OPTIONAL nfs41_path_fh *file,

View file

@ -127,6 +127,20 @@ static int get_superblock_attrs(
if (!bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_DELTA)) if (!bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_DELTA))
superblock->time_delta.seconds = 1; superblock->time_delta.seconds = 1;
/* initialize the default getattr mask */
superblock->default_getattr.count = 2;
superblock->default_getattr.arr[0] = FATTR4_WORD0_TYPE
| FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE
| FATTR4_WORD0_FILEID | FATTR4_WORD0_HIDDEN
| FATTR4_WORD0_ARCHIVE;
superblock->default_getattr.arr[1] = FATTR4_WORD1_MODE
| FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_SYSTEM
| FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_CREATE
| FATTR4_WORD1_TIME_MODIFY;
superblock->default_getattr.arr[2] = 0;
nfs41_superblock_supported_attrs(superblock, &superblock->default_getattr);
dprintf(SBLVL, "attributes for fsid(%llu,%llu): " dprintf(SBLVL, "attributes for fsid(%llu,%llu): "
"maxread=%llu, maxwrite=%llu, layout_types: 0x%X, " "maxread=%llu, maxwrite=%llu, layout_types: 0x%X, "
"cansettime=%u, time_delta={%llu,%u}, aclsupport=%u, " "cansettime=%u, time_delta={%llu,%u}, aclsupport=%u, "
@ -245,38 +259,6 @@ out:
return status; return status;
} }
void nfs41_superblock_supported_attrs(
IN nfs41_superblock *superblock,
IN OUT bitmap4 *attrs)
{
uint32_t i, count = 0;
AcquireSRWLockShared(&superblock->lock);
for (i = 0; i < 3; i++) {
attrs->arr[i] &= superblock->supported_attrs.arr[i];
if (attrs->arr[i])
count = i+1;
}
attrs->count = min(attrs->count, count);
ReleaseSRWLockShared(&superblock->lock);
}
void nfs41_superblock_supported_attrs_exclcreat(
IN nfs41_superblock *superblock,
IN OUT bitmap4 *attrs)
{
uint32_t i, count = 0;
AcquireSRWLockShared(&superblock->lock);
for (i = 0; i < 3; i++) {
attrs->arr[i] &= superblock->suppattr_exclcreat.arr[i];
if (attrs->arr[i])
count = i+1;
}
attrs->count = min(attrs->count, count);
ReleaseSRWLockShared(&superblock->lock);
}
void nfs41_superblock_space_changed( void nfs41_superblock_space_changed(
IN nfs41_superblock *superblock) IN nfs41_superblock *superblock)
{ {

View file

@ -560,7 +560,7 @@ enum pnfs_status pnfs_write(
} else { } else {
/* send a GETATTR to update the cached size */ /* send a GETATTR to update the cached size */
bitmap4 attr_request; bitmap4 attr_request;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(state->file.fh.superblock, &attr_request);
nfs41_getattr(state->session, &state->file, &attr_request, info); nfs41_getattr(state->session, &state->file, &attr_request, info);
} }
out_free_pattern: out_free_pattern:

View file

@ -490,7 +490,7 @@ static int handle_readdir(nfs41_upcall *upcall)
fetch_entries: fetch_entries:
entry_buf_len = max_buf_len; entry_buf_len = max_buf_len;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(state->file.fh.superblock, &attr_request);
attr_request.arr[0] |= FATTR4_WORD0_RDATTR_ERROR; attr_request.arr[0] |= FATTR4_WORD0_RDATTR_ERROR;
if (strchr(args->filter, FILTER_STAR) || strchr(args->filter, FILTER_QM)) { if (strchr(args->filter, FILTER_STAR) || strchr(args->filter, FILTER_QM)) {

View file

@ -232,7 +232,7 @@ retry_write:
} else if (stable == UNSTABLE4) { } else if (stable == UNSTABLE4) {
nfs41_file_info info; nfs41_file_info info;
bitmap4 attr_request; bitmap4 attr_request;
init_getattr_request(&attr_request); nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
status = nfs41_getattr(session, file, &attr_request, &info); status = nfs41_getattr(session, file, &attr_request, &info);
if (status) if (status)
goto out; goto out;

View file

@ -81,6 +81,18 @@ static __inline void bitmap_unset(
mask->count--; mask->count--;
} }
} }
static __inline void bitmap_intersect(
IN bitmap4 *dst,
IN const bitmap4 *src)
{
uint32_t i, count = 0;
for (i = 0; i < 3; i++) {
dst->arr[i] &= src->arr[i];
if (dst->arr[i])
count = i+1;
}
dst->count = min(dst->count, count);
}
ULONG nfs_file_info_to_attributes( ULONG nfs_file_info_to_attributes(
IN const nfs41_file_info *info); IN const nfs41_file_info *info);