From a0d4403a99172e08289a823935f370c466d30809 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 17 Aug 2011 12:11:02 -0400 Subject: [PATCH] deleg: return delegation on attr cache failure on opens that grant a delegation, return the delegation immediately if attribute cache insertion fails nfs41_name_cache_insert() now returns success in the 'out_err_deleg' case, where name cache insertion failed but attr cache insertion was successful Signed-off-by: Casey Bodley --- daemon/name_cache.c | 5 +++-- daemon/nfs41_ops.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/daemon/name_cache.c b/daemon/name_cache.c index c34a365..7d7dfcf 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -909,8 +909,9 @@ out_err_deleg: if (delegation == OPEN_DELEGATE_READ || delegation == OPEN_DELEGATE_WRITE) { /* we still need a reference to the attributes for the delegation */ struct attr_cache_entry *attributes; - if (attr_cache_find_or_create(&cache->attributes, - info->fileid, &attributes) == NO_ERROR) + status = attr_cache_find_or_create(&cache->attributes, + info->fileid, &attributes); + if (status == NO_ERROR) attr_cache_update(attributes, info, delegation); } goto out_unlock; diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index b20d8a5..2dda52e 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -305,6 +305,30 @@ out: return status; } +static void open_delegation_return( + IN nfs41_session *session, + IN nfs41_path_fh *file, + IN open_delegation4 *delegation) +{ + stateid_arg stateid; + int status; + + if (delegation->type == OPEN_DELEGATE_NONE || + delegation->type == OPEN_DELEGATE_NONE_EXT) + return; + + /* return the delegation */ + stateid.open = NULL; + stateid.delegation = NULL; + stateid.type = STATEID_DELEG_FILE; + memcpy(&stateid.stateid, &delegation->stateid, sizeof(stateid4)); + + status = nfs41_delegreturn(session, file, &stateid, TRUE); + + /* clear the delegation type returned by nfs41_open() */ + delegation->type = OPEN_DELEGATE_NONE; +} + int nfs41_open( IN nfs41_session *session, IN nfs41_path_fh *parent, @@ -321,7 +345,7 @@ int nfs41_open( OUT open_delegation4 *delegation, OUT OPTIONAL nfs41_file_info *info) { - int status; + int status, attr_status; nfs41_compound compound; nfs_argop4 argops[8]; nfs_resop4 resops[8]; @@ -459,11 +483,16 @@ int nfs41_open( memcpy(&info->attrmask, &getattr_res.obj_attributes.attrmask, sizeof(bitmap4)); AcquireSRWLockShared(&file->path->lock); - nfs41_name_cache_insert(session_name_cache(session), + attr_status = nfs41_name_cache_insert(session_name_cache(session), file->path->path, &file->name, &file->fh, info, &open_res.resok4.cinfo, delegation->type); ReleaseSRWLockShared(&file->path->lock); + /* if we fail to cache the attributes, return the delegation + * immediately to free resources on the server */ + if (attr_status) + open_delegation_return(session, file, delegation); + if (create == OPEN4_CREATE) nfs41_superblock_space_changed(file->fh.superblock); out: