nfs-ganesha 1.4
|
00001 00033 #ifdef HAVE_CONFIG_H 00034 #include "config.h" 00035 #endif 00036 00037 #ifdef _SOLARIS 00038 #include "solaris_port.h" 00039 #endif /* _SOLARIS */ 00040 00041 #include "fsal.h" 00042 00043 #include "abstract_atomic.h" 00044 #include "log.h" 00045 #include "HashData.h" 00046 #include "HashTable.h" 00047 #include "cache_inode.h" 00048 #include "cache_inode_lru.h" 00049 00050 #include <unistd.h> 00051 #include <string.h> 00052 #include <sys/types.h> 00053 #include <sys/stat.h> 00054 #include <sys/param.h> 00055 #include <time.h> 00056 #include <pthread.h> 00057 #include <strings.h> 00058 #include <assert.h> 00059 00072 fsal_file_t * 00073 cache_inode_fd(cache_entry_t *entry) 00074 { 00075 if (entry == NULL) { 00076 return NULL; 00077 } 00078 00079 if (entry->type != REGULAR_FILE) { 00080 return NULL; 00081 } 00082 00083 if (entry->object.file.open_fd.openflags != FSAL_O_CLOSED) { 00084 return &entry->object.file.open_fd.fd; 00085 } 00086 00087 return NULL; 00088 } 00089 00101 bool_t 00102 is_open_for_write(cache_entry_t *entry) 00103 { 00104 return 00105 (entry && 00106 (entry->type == REGULAR_FILE) && 00107 ((entry->object.file.open_fd.openflags == FSAL_O_RDWR) || 00108 (entry->object.file.open_fd.openflags == FSAL_O_WRONLY))); 00109 } 00110 00122 bool_t 00123 is_open_for_read(cache_entry_t *entry) 00124 { 00125 return 00126 (entry && 00127 (entry->type == REGULAR_FILE) && 00128 ((entry->object.file.open_fd.openflags == FSAL_O_RDWR) || 00129 (entry->object.file.open_fd.openflags == FSAL_O_RDONLY))); 00130 } 00131 00147 cache_inode_status_t 00148 cache_inode_open(cache_entry_t *entry, 00149 fsal_openflags_t openflags, 00150 fsal_op_context_t *context, 00151 uint32_t flags, 00152 cache_inode_status_t *status) 00153 { 00154 /* Error return from FSAL */ 00155 fsal_status_t fsal_status = {0, 0}; 00156 00157 if ((entry == NULL) || (context == NULL) || 00158 (status == NULL)) { 00159 *status = CACHE_INODE_INVALID_ARGUMENT; 00160 goto out; 00161 } 00162 00163 if (entry->type != REGULAR_FILE) { 00164 *status = CACHE_INODE_BAD_TYPE; 00165 goto out; 00166 } 00167 00168 if (!cache_inode_lru_fds_available()) { 00169 /* This seems the best idea, let the client try again later 00170 after the reap. */ 00171 *status = CACHE_INODE_DELAY; 00172 goto out; 00173 } 00174 00175 if (!(flags & CACHE_INODE_FLAG_CONTENT_HAVE)) { 00176 pthread_rwlock_wrlock(&entry->content_lock); 00177 } 00178 00179 /* Open file need to be closed, unless it is already open as read/write */ 00180 if ((entry->object.file.open_fd.openflags != FSAL_O_RDWR) && 00181 (entry->object.file.open_fd.openflags != 0) && 00182 (entry->object.file.open_fd.openflags != openflags)) { 00183 fsal_status = FSAL_close(&(entry->object.file.open_fd.fd)); 00184 if (FSAL_IS_ERROR(fsal_status) && 00185 (fsal_status.major != ERR_FSAL_NOT_OPENED)) { 00186 *status = cache_inode_error_convert(fsal_status); 00187 if (fsal_status.major == ERR_FSAL_STALE) { 00188 cache_inode_kill_entry(entry); 00189 } 00190 00191 LogDebug(COMPONENT_CACHE_INODE, 00192 "cache_inode_open: returning %d(%s) from FSAL_close", 00193 *status, cache_inode_err_str(*status)); 00194 00195 goto unlock; 00196 } 00197 00198 if (!FSAL_IS_ERROR(fsal_status)) 00199 atomic_dec_size_t(&open_fd_count); 00200 00201 /* Force re-openning */ 00202 entry->object.file.open_fd.openflags = FSAL_O_CLOSED; 00203 } 00204 00205 if ((entry->object.file.open_fd.openflags == FSAL_O_CLOSED)) { 00206 fsal_status = FSAL_open(&(entry->handle), 00207 context, 00208 openflags, 00209 &entry->object.file.open_fd.fd, 00210 NULL); 00211 if (FSAL_IS_ERROR(fsal_status)) { 00212 *status = cache_inode_error_convert(fsal_status); 00213 LogDebug(COMPONENT_CACHE_INODE, 00214 "cache_inode_open: returning %d(%s) from FSAL_open", 00215 *status, cache_inode_err_str(*status)); 00216 if (fsal_status.major == ERR_FSAL_STALE) { 00217 cache_inode_kill_entry(entry); 00218 } 00219 goto unlock; 00220 } 00221 00222 entry->object.file.open_fd.openflags = openflags; 00223 /* This is temporary code, until Jim Lieb makes FSALs cache 00224 their own file descriptors. Under that regime, the LRU 00225 thread will interrogate FSALs for their FD use. */ 00226 atomic_inc_size_t(&open_fd_count); 00227 00228 LogDebug(COMPONENT_CACHE_INODE, 00229 "cache_inode_open: pentry %p: openflags = %d, " 00230 "open_fd_count = %zd", entry, openflags, 00231 open_fd_count); 00232 } 00233 00234 *status = CACHE_INODE_SUCCESS; 00235 00236 unlock: 00237 00238 if (!(flags & CACHE_INODE_FLAG_CONTENT_HOLD)) { 00239 pthread_rwlock_unlock(&entry->content_lock); 00240 } 00241 00242 out: 00243 00244 return *status; 00245 00246 } /* cache_inode_open */ 00247 00260 cache_inode_status_t 00261 cache_inode_close(cache_entry_t *entry, 00262 uint32_t flags, 00263 cache_inode_status_t *status) 00264 { 00265 /* Error return from the FSAL */ 00266 fsal_status_t fsal_status; 00267 00268 if ((entry == NULL) || (status == NULL)) { 00269 *status = CACHE_INODE_INVALID_ARGUMENT; 00270 goto out; 00271 } 00272 00273 if (entry->type != REGULAR_FILE) { 00274 *status = CACHE_INODE_BAD_TYPE; 00275 goto out; 00276 } 00277 00278 if (!(flags & CACHE_INODE_FLAG_CONTENT_HAVE)) { 00279 pthread_rwlock_wrlock(&entry->content_lock); 00280 } 00281 00282 /* If nothing is opened, do nothing */ 00283 if (entry->object.file.open_fd.openflags == FSAL_O_CLOSED) { 00284 if (!(flags & CACHE_INODE_FLAG_CONTENT_HOLD)) { 00285 pthread_rwlock_unlock(&entry->content_lock); 00286 } 00287 *status = CACHE_INODE_SUCCESS; 00288 return *status; 00289 } 00290 00291 /* If state is held in the file, do not close it. This should 00292 be refined. (A non return_on_close layout should not prevent 00293 the file from closing.) The caller should hold the state 00294 lock. */ 00295 if (cache_inode_file_holds_state(entry)) { 00296 *status = CACHE_INODE_SUCCESS; 00297 goto unlock; 00298 } 00299 00300 if (!cache_inode_lru_caching_fds() || 00301 (flags & CACHE_INODE_FLAG_REALLYCLOSE)) { 00302 LogDebug(COMPONENT_CACHE_INODE, 00303 "cache_inode_close: entry %p", entry); 00304 fsal_status = FSAL_close(&(entry->object.file.open_fd.fd)); 00305 00306 entry->object.file.open_fd.openflags = FSAL_O_CLOSED; 00307 if (FSAL_IS_ERROR(fsal_status) && 00308 (fsal_status.major != ERR_FSAL_NOT_OPENED)) { 00309 *status = cache_inode_error_convert(fsal_status); 00310 if (fsal_status.major == ERR_FSAL_STALE) { 00311 cache_inode_kill_entry(entry); 00312 } 00313 LogCrit(COMPONENT_CACHE_INODE, 00314 "cache_inode_close: returning %d(%s) from FSAL_close", 00315 *status, cache_inode_err_str(*status)); 00316 goto unlock; 00317 } 00318 if (!FSAL_IS_ERROR(fsal_status)) 00319 atomic_dec_size_t(&open_fd_count); 00320 } 00321 00322 *status = CACHE_INODE_SUCCESS; 00323 00324 unlock: 00325 00326 if (!(flags & CACHE_INODE_FLAG_CONTENT_HOLD)) { 00327 pthread_rwlock_unlock(&entry->content_lock); 00328 } 00329 00330 out: 00331 00332 return *status; 00333 }