diff --git a/daemon/getattr.c b/daemon/getattr.c index 541237b..61e53ce 100644 --- a/daemon/getattr.c +++ b/daemon/getattr.c @@ -45,7 +45,7 @@ int nfs41_cached_getattr( if (status) { /* fetch attributes from the server */ 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); if (status) { diff --git a/daemon/nfs41.h b/daemon/nfs41.h index acf017c..ee003cf 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -22,7 +22,7 @@ #ifndef __NFS41__ #define __NFS41__ -#include "nfs41_types.h" +#include "util.h" #include "list.h" @@ -33,12 +33,15 @@ struct __nfs41_root; typedef struct __nfs41_superblock { nfs41_fsid fsid; + struct list_entry entry; /* position in nfs41_server.superblocks */ + bitmap4 supported_attrs; bitmap4 suppattr_exclcreat; + bitmap4 default_getattr; + nfstime4 time_delta; uint64_t maxread; uint64_t maxwrite; - struct list_entry entry; /* position in nfs41_server.superblocks */ /* constant filesystem attributes */ unsigned int layout_types : 3; @@ -420,13 +423,24 @@ int nfs41_superblock_for_fh( IN const nfs41_fh *parent OPTIONAL, OUT nfs41_path_fh *file); -void nfs41_superblock_supported_attrs( - IN nfs41_superblock *superblock, - IN OUT bitmap4 *attrs); - -void nfs41_superblock_supported_attrs_exclcreat( - IN nfs41_superblock *superblock, - IN OUT bitmap4 *attrs); +static __inline void nfs41_superblock_getattr_mask( + IN const nfs41_superblock *superblock, + OUT bitmap4 *attrs) +{ + memcpy(attrs, &superblock->default_getattr, sizeof(bitmap4)); +} +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( IN nfs41_superblock *superblock); diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index 67a46a6..80f6d1a 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -412,6 +412,7 @@ int nfs41_open( current_fh_is_dir = TRUE; /* SEQUENCE; PUTFH(dir); SAVEFH; OPEN; * GETFH(file); GETATTR(file); RESTOREFH(dir); GETATTR */ + nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request); break; case CLAIM_PREVIOUS: case CLAIM_FH: @@ -421,13 +422,13 @@ int nfs41_open( /* CURRENT_FH: file being opened */ current_fh_is_dir = FALSE; /* SEQUENCE; PUTFH(file); OPEN; GETATTR(file); PUTFH(dir); GETATTR */ + nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request); break; } if (info == NULL) info = &tmp_info; - init_getattr_request(&attr_request); attr_request.arr[0] |= FATTR4_WORD0_FSID; compound_init(&compound, argops, resops, "open"); @@ -556,7 +557,7 @@ int nfs41_create( nfs41_savefh_res savefh_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"); @@ -648,7 +649,7 @@ int nfs41_close( bitmap4 attr_request; nfs41_file_info info; - init_getattr_request(&attr_request); + nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request); compound_init(&compound, argops, resops, "close"); @@ -713,7 +714,7 @@ int nfs41_write( bitmap4 attr_request; 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, stateid->stateid.seqid == 0 ? "ds write" : "write"); @@ -887,7 +888,7 @@ int nfs41_commit( if (cinfo) pinfo = cinfo; else pinfo = &info; 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); getattr_args.attr_request = &attr_request; @@ -1079,18 +1080,6 @@ out: 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( IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *file, @@ -1167,7 +1156,7 @@ int nfs41_remove( bitmap4 attr_request; nfs41_file_info info; - init_getattr_request(&attr_request); + nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request); compound_init(&compound, argops, resops, "remove"); @@ -1238,7 +1227,7 @@ int nfs41_rename( bitmap4 attr_request; 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"); @@ -1353,7 +1342,7 @@ int nfs41_setattr( setattr_args.stateid = stateid; 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); getattr_args.attr_request = &attr_request; getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; @@ -1402,8 +1391,8 @@ int nfs41_link( nfs41_file_info info = { 0 }; nfs41_path_fh file; - init_getattr_request(&info.attrmask); - init_getattr_request(&cinfo->attrmask); + nfs41_superblock_getattr_mask(src->fh.superblock, &info.attrmask); + nfs41_superblock_getattr_mask(dst_dir->fh.superblock, &cinfo->attrmask); cinfo->attrmask.arr[0] |= FATTR4_WORD0_FSID; compound_init(&compound, argops, resops, "link"); @@ -2018,7 +2007,7 @@ enum nfsstat4 pnfs_rpc_layoutcommit( nfs41_getattr_res getattr_res; bitmap4 attr_request; - init_getattr_request(&attr_request); + nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request); compound_init(&compound, argops, resops, "layoutcommit"); diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h index 7217942..f51d6ad 100644 --- a/daemon/nfs41_ops.h +++ b/daemon/nfs41_ops.h @@ -1123,9 +1123,6 @@ int nfs41_readdir( IN OUT uint32_t *entries_len, OUT bool_t *eof_out); -void init_getattr_request( - OUT bitmap4 *attr_request); - int nfs41_getattr( IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *file, diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c index a8c2253..eebfe96 100644 --- a/daemon/nfs41_superblock.c +++ b/daemon/nfs41_superblock.c @@ -127,6 +127,20 @@ static int get_superblock_attrs( if (!bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_DELTA)) 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): " "maxread=%llu, maxwrite=%llu, layout_types: 0x%X, " "cansettime=%u, time_delta={%llu,%u}, aclsupport=%u, " @@ -245,38 +259,6 @@ out: 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( IN nfs41_superblock *superblock) { diff --git a/daemon/pnfs_io.c b/daemon/pnfs_io.c index 6386ad0..34f9ad5 100644 --- a/daemon/pnfs_io.c +++ b/daemon/pnfs_io.c @@ -560,7 +560,7 @@ enum pnfs_status pnfs_write( } else { /* send a GETATTR to update the cached size */ 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); } out_free_pattern: diff --git a/daemon/readdir.c b/daemon/readdir.c index c210234..5bc06c0 100644 --- a/daemon/readdir.c +++ b/daemon/readdir.c @@ -490,7 +490,7 @@ static int handle_readdir(nfs41_upcall *upcall) fetch_entries: 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; if (strchr(args->filter, FILTER_STAR) || strchr(args->filter, FILTER_QM)) { diff --git a/daemon/readwrite.c b/daemon/readwrite.c index 3a1e080..c62ce4b 100644 --- a/daemon/readwrite.c +++ b/daemon/readwrite.c @@ -232,7 +232,7 @@ retry_write: } else if (stable == UNSTABLE4) { nfs41_file_info info; 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); if (status) goto out; diff --git a/daemon/util.h b/daemon/util.h index 0cf2c4a..60d3ea0 100644 --- a/daemon/util.h +++ b/daemon/util.h @@ -81,6 +81,18 @@ static __inline void bitmap_unset( 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( IN const nfs41_file_info *info);