From a085a8979b50e939d5ea08cb48598168a2d1c98a Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 21 Feb 2012 18:01:32 -0800 Subject: [PATCH] deleg: fix for attributes in CB_GETATTR CB_GETATTR specifies the delegation by filehandle, but deleg_fh_cmp() was comparing superblock and fileid. renamed deleg_fh_cmp() to deleg_file_cmp(), and created new deleg_fh_cmp() to compare actual filehandles call to nfs41_attr_cache_lookup() was not setting flags in info.attrmask, so the change and size attributes were not being encoded in the CB_GETATTR response Signed-off-by: Casey Bodley --- daemon/delegation.c | 18 +++++++++++++----- daemon/name_cache.c | 7 +++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/daemon/delegation.c b/daemon/delegation.c index ee89d28..7b2611b 100644 --- a/daemon/delegation.c +++ b/daemon/delegation.c @@ -381,7 +381,7 @@ out_return: /* return the delegation on failure */ #define deleg_entry(pos) list_container(pos, nfs41_delegation_state, client_entry) -static int deleg_fh_cmp(const struct list_entry *entry, const void *value) +static int deleg_file_cmp(const struct list_entry *entry, const void *value) { const nfs41_fh *lhs = &deleg_entry(entry)->file.fh; const nfs41_fh *rhs = (const nfs41_fh*)value; @@ -484,7 +484,7 @@ int nfs41_delegate_open( int status; /* search for a delegation with this filehandle */ - status = delegation_find(client, &file->fh, deleg_fh_cmp, &deleg); + status = delegation_find(client, &file->fh, deleg_file_cmp, &deleg); if (status) goto out; @@ -622,7 +622,7 @@ void nfs41_delegation_remove_srvopen( nfs41_delegation_state *deleg = NULL; /* find a delegation for this file */ - if (delegation_find(session->client, &file->fh, deleg_fh_cmp, &deleg) || !deleg) + if (delegation_find(session->client, &file->fh, deleg_file_cmp, &deleg)) return; dprintf(1, "nfs41_delegation_remove_srvopen: removing reference to " "srv_open=%x\n", deleg->srv_open); @@ -645,7 +645,7 @@ int nfs41_delegation_return( int status; /* find a delegation for this file */ - status = delegation_find(client, &file->fh, deleg_fh_cmp, &deleg); + status = delegation_find(client, &file->fh, deleg_file_cmp, &deleg); if (status) goto out; @@ -717,7 +717,7 @@ int nfs41_delegation_recall( dprintf(2, "--> nfs41_delegation_recall()\n"); /* search for the delegation by stateid instead of filehandle; - * deleg_fh_cmp() relies on a proper superblock and fileid, + * deleg_file_cmp() relies on a proper superblock and fileid, * which we don't get with CB_RECALL */ status = delegation_find(client, stateid, deleg_stateid_cmp, &deleg); if (status) @@ -776,6 +776,14 @@ out_deleg: } +static int deleg_fh_cmp(const struct list_entry *entry, const void *value) +{ + const nfs41_fh *lhs = &deleg_entry(entry)->file.fh; + const nfs41_fh *rhs = (const nfs41_fh*)value; + if (lhs->len != rhs->len) return -1; + return memcmp(lhs->fh, rhs->fh, lhs->len); +} + int nfs41_delegation_getattr( IN nfs41_client *client, IN const nfs41_fh *fh, diff --git a/daemon/name_cache.c b/daemon/name_cache.c index e064739..786aef7 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -337,6 +337,13 @@ static void copy_attrs( dst->numlinks = src->numlinks; dst->mode = src->mode; dst->fileid = src->fileid; + + dst->attrmask.count = 2; + dst->attrmask.arr[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE + | FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID; + dst->attrmask.arr[1] = FATTR4_WORD1_MODE + | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_TIME_ACCESS + | FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_MODIFY; }