From 68d97f5400d979f4d69a7dd440f8978143b7405c Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 29 Mar 2012 14:40:12 -0400 Subject: [PATCH] open: use suppattr_exclcreat to mask exclusive create attributes Signed-off-by: Casey Bodley --- daemon/nfs41.h | 5 +++++ daemon/nfs41_ops.c | 9 ++++++++- daemon/nfs41_superblock.c | 20 +++++++++++++++++++- daemon/nfs41_types.h | 1 + daemon/nfs41_xdr.c | 4 ++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/daemon/nfs41.h b/daemon/nfs41.h index 8ced537..acf017c 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -34,6 +34,7 @@ struct __nfs41_root; typedef struct __nfs41_superblock { nfs41_fsid fsid; bitmap4 supported_attrs; + bitmap4 suppattr_exclcreat; nfstime4 time_delta; uint64_t maxread; uint64_t maxwrite; @@ -423,6 +424,10 @@ 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); + void nfs41_superblock_space_changed( IN nfs41_superblock *superblock); diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index c4bc4e3..fffcca7 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -466,7 +466,14 @@ int nfs41_open( if (how_mode == EXCLUSIVE4_1) { DWORD tid = GetCurrentThreadId(); time((time_t*)open_args.openhow.how.createverf); - memcpy(open_args.openhow.how.createverf+4, &tid, sizeof(tid)); + memcpy(open_args.openhow.how.createverf+4, &tid, sizeof(tid)); + /* mask unsupported attributes */ + nfs41_superblock_supported_attrs_exclcreat( + parent->fh.superblock, &createattrs->attrmask); + } else { + /* mask unsupported attributes */ + nfs41_superblock_supported_attrs( + parent->fh.superblock, &createattrs->attrmask); } open_args.claim = claim; open_res.resok4.stateid = stateid; diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c index cf2bf4a..a8c2253 100644 --- a/daemon/nfs41_superblock.c +++ b/daemon/nfs41_superblock.c @@ -86,9 +86,11 @@ static int get_superblock_attrs( 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; + attr_request.arr[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT; + attr_request.count = 3; info.supported_attrs = &superblock->supported_attrs; + info.suppattr_exclcreat = &superblock->suppattr_exclcreat; info.time_delta = &superblock->time_delta; status = nfs41_getattr(session, file, &attr_request, &info); @@ -259,6 +261,22 @@ void nfs41_superblock_supported_attrs( 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/nfs41_types.h b/daemon/nfs41_types.h index 1e5e716..61d46a3 100644 --- a/daemon/nfs41_types.h +++ b/daemon/nfs41_types.h @@ -207,6 +207,7 @@ typedef struct __nfs41_file_info { nfstime4 *time_delta; /* XXX: per-fs */ bitmap4 attrmask; bitmap4 *supported_attrs; /* XXX: per-fs */ + bitmap4 *suppattr_exclcreat; /* XXX: per-fs */ uint64_t maxread; /* XXX: per-fs */ uint64_t maxwrite; /* XXX: per-fs */ uint64_t change; diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c index 990c648..a23d8b4 100644 --- a/daemon/nfs41_xdr.c +++ b/daemon/nfs41_xdr.c @@ -1851,6 +1851,10 @@ static bool_t decode_file_attrs( if (!xdr_mdsthreshold(xdr, &info->mdsthreshold)) return FALSE; } + if (attrs->attrmask.arr[2] & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { + if (!xdr_bitmap4(xdr, info->suppattr_exclcreat)) + return FALSE; + } } return TRUE; }