nfs-ganesha 1.4
|
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 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00031 #ifdef HAVE_CONFIG_H 00032 #include "config.h" 00033 #endif 00034 00035 #ifdef _SOLARIS 00036 #include "solaris_port.h" 00037 #endif /* _SOLARIS */ 00038 00039 #include "abstract_atomic.h" 00040 #include "log.h" 00041 #include "HashData.h" 00042 #include "HashTable.h" 00043 #include "fsal.h" 00044 #include "cache_inode.h" 00045 #include "cache_inode_lru.h" 00046 00047 #include <unistd.h> 00048 #include <sys/types.h> 00049 #include <sys/param.h> 00050 #include <time.h> 00051 #include <pthread.h> 00052 #include <assert.h> 00053 00074 cache_inode_status_t 00075 cache_inode_invalidate(cache_inode_fsal_data_t *fsal_data, 00076 cache_inode_status_t *status, 00077 uint32_t flags) 00078 { 00079 hash_buffer_t key, value; 00080 int rc = 0 ; 00081 cache_entry_t *entry; 00082 struct hash_latch latch; 00083 00084 if (status == NULL || fsal_data == NULL) { 00085 *status = CACHE_INODE_INVALID_ARGUMENT; 00086 goto out; 00087 } 00088 00089 /* Locate the entry in the cache */ 00090 FSAL_ExpandHandle(NULL, /* pcontext but not used... */ 00091 FSAL_DIGEST_SIZEOF, 00092 &fsal_data->fh_desc); 00093 00094 /* Turn the input to a hash key */ 00095 key.pdata = fsal_data->fh_desc.start; 00096 key.len = fsal_data->fh_desc.len; 00097 00098 if ((rc = HashTable_GetLatch(fh_to_cache_entry_ht, 00099 &key, 00100 &value, 00101 FALSE, 00102 &latch)) == HASHTABLE_ERROR_NO_SUCH_KEY) { 00103 /* Entry is not cached */ 00104 HashTable_ReleaseLatched(fh_to_cache_entry_ht, &latch); 00105 *status = CACHE_INODE_NOT_FOUND; 00106 return *status; 00107 } else if (rc != HASHTABLE_SUCCESS) { 00108 LogCrit(COMPONENT_CACHE_INODE, 00109 "Unexpected error %u while calling HashTable_GetLatch", rc) ; 00110 *status = CACHE_INODE_INVALID_ARGUMENT; 00111 goto out; 00112 } 00113 00114 entry = value.pdata; 00115 if (cache_inode_lru_ref(entry, 0) != CACHE_INODE_SUCCESS) { 00116 HashTable_ReleaseLatched(fh_to_cache_entry_ht, &latch); 00117 *status = CACHE_INODE_NOT_FOUND; 00118 return *status; 00119 } 00120 HashTable_ReleaseLatched(fh_to_cache_entry_ht, &latch); 00121 00122 pthread_rwlock_wrlock(&entry->attr_lock); 00123 pthread_rwlock_wrlock(&entry->content_lock); 00124 00125 /* We can invalidate entries with state just fine. We force 00126 Cache_inode to contact the FSAL for any use of content or 00127 attributes, and if the FSAL indicates the entry is stale, it 00128 can be disposed of then. */ 00129 00130 /* We should have a way to invalidate content and attributes 00131 separately. Or at least a way to invalidate attributes 00132 without invalidating content (since any change in content 00133 really ought to modify mtime, at least.) */ 00134 00135 if (flags == CACHE_INODE_INVALIDATE_CLEARBITS) 00136 atomic_clear_uint32_t_bits(&entry->flags, 00137 CACHE_INODE_TRUST_ATTRS | 00138 CACHE_INODE_DIR_POPULATED | 00139 CACHE_INODE_TRUST_CONTENT); 00140 00141 /* The main reason for holding the lock at this point is so we 00142 don't clear the trust bits while someone is populating the 00143 directory or refreshing attributes. */ 00144 00145 if ((flags == CACHE_INODE_INVALIDATE_CLOSE) && 00146 (entry->type == REGULAR_FILE)) { 00147 cache_inode_close(entry, 00148 (CACHE_INODE_FLAG_REALLYCLOSE | 00149 CACHE_INODE_FLAG_CONTENT_HAVE | 00150 CACHE_INODE_FLAG_CONTENT_HOLD), 00151 status); 00152 } 00153 00154 pthread_rwlock_unlock(&entry->attr_lock); 00155 pthread_rwlock_unlock(&entry->content_lock); 00156 00157 cache_inode_lru_unref(entry, 0); 00158 00159 out: 00160 00161 /* Memory copying attributes with every call is expensive. 00162 Let's not do it. */ 00163 00164 return (*status); 00165 } /* cache_inode_invalidate */