diff --git a/daemon/nfs41.h b/daemon/nfs41.h index d385b7c..c47fda0 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -35,9 +35,11 @@ struct __rpc_client; typedef struct __nfs41_superblock { nfs41_fsid fsid; bitmap4 supported_attrs; + nfstime4 time_delta; uint64_t maxread; uint64_t maxwrite; uint32_t layout_types; + bool_t cansettime; struct list_entry entry; /* position in nfs41_server.superblocks */ SRWLOCK lock; diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c index 38a13f9..1c33e0c 100644 --- a/daemon/nfs41_superblock.c +++ b/daemon/nfs41_superblock.c @@ -87,13 +87,16 @@ static int get_superblock_attrs( bitmap4 attr_request; nfs41_file_info info; - attr_request.arr[0] = (uint32_t)(FATTR4_WORD0_SUPPORTED_ATTRS | - FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE); - attr_request.arr[1] = FATTR4_WORD1_FS_LAYOUT_TYPE; + attr_request.arr[0] = FATTR4_WORD0_SUPPORTED_ATTRS | + FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_MAXREAD | + (uint32_t)(FATTR4_WORD0_MAXWRITE); + attr_request.arr[1] = FATTR4_WORD1_FS_LAYOUT_TYPE | + FATTR4_WORD1_TIME_DELTA; attr_request.count = 2; ZeroMemory(&info, sizeof(info)); info.supported_attrs = &superblock->supported_attrs; + info.time_delta = &superblock->time_delta; status = nfs41_getattr(session, file, &attr_request, &info); if (status) { @@ -116,11 +119,22 @@ static int get_superblock_attrs( superblock->layout_types = info.fs_layout_types; + if (bitmap_isset(&info.attrmask, 0, FATTR4_WORD0_CANSETTIME)) + superblock->cansettime = info.cansettime; + else /* cansettime is not supported, try setting them anyway */ + superblock->cansettime = 1; + + /* if time_delta is not supported, default to 1s */ + if (!bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_DELTA)) + superblock->time_delta.seconds = 1; + dprintf(SBLVL, "attributes for fsid(%llu,%llu): " - "maxread=%llu, maxwrite=%llu, layout_types: 0x%X\n", + "maxread=%llu, maxwrite=%llu, layout_types: 0x%X, " + "cansettime=%u, time_delta={%ll,%u}\n", superblock->fsid.major, superblock->fsid.minor, superblock->maxread, superblock->maxwrite, - superblock->layout_types); + superblock->layout_types, superblock->cansettime, + superblock->time_delta.seconds, superblock->time_delta.nseconds); out: return status; } diff --git a/daemon/nfs41_types.h b/daemon/nfs41_types.h index a3a238e..3ce9bd7 100644 --- a/daemon/nfs41_types.h +++ b/daemon/nfs41_types.h @@ -161,6 +161,7 @@ typedef struct __nfs41_file_info { nfstime4 time_access; nfstime4 time_create; nfstime4 time_modify; + nfstime4 *time_delta; /* XXX: per-fs */ bitmap4 attrmask; bitmap4 *supported_attrs; /* XXX: per-fs */ uint64_t maxread; /* XXX: per-fs */ @@ -180,6 +181,7 @@ 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 cansettime; /* XXX: per-fs */ bool_t case_insensitive; bool_t case_preserving; } nfs41_file_info; diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c index 2642f2e..7699837 100644 --- a/daemon/nfs41_xdr.c +++ b/daemon/nfs41_xdr.c @@ -1546,6 +1546,10 @@ static bool_t decode_file_attrs( if (!xdr_u_int32_t(xdr, &info->rdattr_error)) return FALSE; } + if (attrs->attrmask.arr[0] & FATTR4_WORD0_CANSETTIME) { + if (!xdr_bool(xdr, &info->cansettime)) + return FALSE; + } if (attrs->attrmask.arr[0] & FATTR4_WORD0_CASE_INSENSITIVE) { if (!xdr_bool(xdr, &info->case_insensitive)) return FALSE; @@ -1600,6 +1604,10 @@ static bool_t decode_file_attrs( if (!xdr_nfstime4(xdr, &info->time_create)) return FALSE; } + if (attrs->attrmask.arr[1] & FATTR4_WORD1_TIME_DELTA) { + if (!xdr_nfstime4(xdr, info->time_delta)) + return FALSE; + } if (attrs->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) { if (!xdr_nfstime4(xdr, &info->time_modify)) return FALSE;