nfs-ganesha 1.4

cache_inode_lookupp.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00022  * 02110-1301 USA
00023  *
00024  * ---------------------------------------
00025  */
00026 
00038 #ifdef HAVE_CONFIG_H
00039 #include "config.h"
00040 #endif
00041 
00042 #ifdef _SOLARIS
00043 #include "solaris_port.h"
00044 #endif                          /* _SOLARIS */
00045 
00046 #include "log.h"
00047 #include "HashData.h"
00048 #include "HashTable.h"
00049 #include "fsal.h"
00050 #include "cache_inode.h"
00051 #include "cache_inode_lru.h"
00052 #include "cache_inode_weakref.h"
00053 
00054 #include <unistd.h>
00055 #include <sys/types.h>
00056 #include <sys/param.h>
00057 #include <time.h>
00058 #include <pthread.h>
00059 #include <assert.h>
00060 
00080 cache_entry_t *
00081 cache_inode_lookupp_impl(cache_entry_t *entry,
00082                          fsal_op_context_t *context,
00083                          cache_inode_status_t *status)
00084 {
00085      cache_entry_t *parent = NULL;
00086      fsal_status_t fsal_status;
00087      fsal_attrib_list_t object_attributes;
00088      cache_inode_fsal_data_t fsdata;
00089 
00090      /* Set the return default to CACHE_INODE_SUCCESS */
00091      *status = CACHE_INODE_SUCCESS;
00092 
00093      /* Never even think of calling FSAL_lookup on root/.. */
00094 
00095      if (entry->object.dir.root) {
00096           /* Bump the refcount on the current entry (so the caller's
00097              releasing decrementing it doesn't take us below the
00098              sentinel count */
00099           if (cache_inode_lru_ref(entry, 0) !=
00100               CACHE_INODE_SUCCESS) {
00101                /* This cannot actually happen */
00102                LogFatal(COMPONENT_CACHE_INODE,
00103                         "There has been a grave failure in consistency: "
00104                         "Unable to increment reference count on an entry that "
00105                         "on which we should have a referenced.");
00106           }
00107           return entry;
00108      }
00109 
00110      /* Try the weakref to the parent first.  This increments the
00111         refcount. */
00112      parent = cache_inode_weakref_get(&entry->object.dir.parent,
00113                                       LRU_REQ_INITIAL);
00114      if (!parent) {
00115           /* If we didn't find it, drop the read lock, get a write
00116              lock, and make sure nobody filled it in while we waited. */
00117           pthread_rwlock_unlock(&entry->content_lock);
00118           pthread_rwlock_wrlock(&entry->content_lock);
00119           parent = cache_inode_weakref_get(&entry->object.dir.parent,
00120                                            LRU_REQ_INITIAL);
00121      }
00122 
00123      if (!parent) {
00124           fsal_handle_t parent_handle;
00125           memset(&parent_handle, 0, sizeof(fsal_handle_t));
00126 
00127           memset(&object_attributes, 0, sizeof(fsal_attrib_list_t));
00128           object_attributes.asked_attributes = cache_inode_params.attrmask;
00129           fsal_status =
00130                FSAL_lookup(&entry->handle, (fsal_name_t *) &FSAL_DOT_DOT,
00131                            context, &parent_handle, &object_attributes);
00132 
00133           if(FSAL_IS_ERROR(fsal_status)) {
00134                if (fsal_status.major == ERR_FSAL_STALE) {
00135                     cache_inode_kill_entry(entry);
00136                }
00137                *status = cache_inode_error_convert(fsal_status);
00138                return NULL;
00139           }
00140 
00141           /* Call cache_inode_get to populate the cache with the parent entry */
00142           fsdata.fh_desc.start = (caddr_t) &parent_handle;
00143           fsdata.fh_desc.len = 0;
00144           FSAL_ExpandHandle(context->export_context,
00145                             FSAL_DIGEST_SIZEOF,
00146                             &fsdata.fh_desc);
00147 
00148 
00149           /* Call cache_inode_get to populate the cache with the
00150              parent entry.  This increments the refcount. */
00151           if((parent = cache_inode_get(&fsdata,
00152                                        &object_attributes,
00153                                        context,
00154                                        entry,
00155                                        status)) == NULL) {
00156                return NULL;
00157           }
00158 
00159           /* Link in a weak reference */
00160           entry->object.dir.parent = parent->weakref;
00161      }
00162 
00163      return parent;
00164 } /* cache_inode_lookupp_impl */
00165 
00182 cache_entry_t *
00183 cache_inode_lookupp(cache_entry_t *entry,
00184                     fsal_op_context_t *context,
00185                     cache_inode_status_t *status)
00186 {
00187      cache_entry_t *parent = NULL;
00188      pthread_rwlock_rdlock(&entry->content_lock);
00189      parent = cache_inode_lookupp_impl(entry, context, status);
00190      pthread_rwlock_unlock(&entry->content_lock);
00191      return parent;
00192 } /* cache_inode_lookupp */