nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright (C) 2011, Linux Box Corporation 00005 * contributor: Adam C. Emerson 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License 00009 * as published by the Free Software Foundation; either version 3 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00020 * 02110-1301 USA 00021 * 00022 * --------------------------------------- 00023 */ 00024 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 <unistd.h> 00042 #include <sys/types.h> 00043 #include <sys/param.h> 00044 #include <time.h> 00045 #include <pthread.h> 00046 #include <string.h> 00047 00048 #include "LRU_List.h" 00049 #include "log.h" 00050 #include "HashData.h" 00051 #include "HashTable.h" 00052 #include "fsal.h" 00053 #include "sal_functions.h" 00054 #include "nfs_core.h" 00055 00075 state_status_t 00076 state_add_segment(state_t *state, 00077 struct pnfs_segment *segment, 00078 void *fsal_data, 00079 bool_t return_on_close) 00080 { 00081 /* Pointer to the new segment being added to the state */ 00082 state_layout_segment_t *new_segment = NULL; 00083 00084 if (state->state_type != STATE_TYPE_LAYOUT) { 00085 LogCrit(COMPONENT_PNFS, "Attempt to add layout segment to " 00086 "non-layout state: %p", state); 00087 return STATE_BAD_TYPE; 00088 } 00089 00090 new_segment = gsh_calloc(1, sizeof(*new_segment)); 00091 if(!new_segment) { 00092 return STATE_MALLOC_ERROR; 00093 } 00094 00095 if(pthread_mutex_init(&new_segment->sls_mutex, NULL) == -1) { 00096 gsh_free(new_segment); 00097 return STATE_POOL_MUTEX_INIT_ERROR; 00098 } 00099 00100 new_segment->sls_fsal_data = fsal_data; 00101 new_segment->sls_state = state; 00102 new_segment->sls_segment = *segment; 00103 00104 glist_add_tail(&state->state_data.layout.state_segments, 00105 &new_segment->sls_state_segments); 00106 00107 /* Based on comments by Benny Halevy, if any segment is marked 00108 return_on_close, all segments should be treated as 00109 return_on_close. */ 00110 if (return_on_close) { 00111 state->state_data.layout.state_return_on_close = TRUE; 00112 } 00113 00114 return STATE_SUCCESS; 00115 } 00116 00117 /* This function must be called with the mutex lock held */ 00118 00119 state_status_t state_delete_segment(state_layout_segment_t *segment) { 00120 glist_del(&segment->sls_state_segments); 00121 pthread_mutex_unlock(&segment->sls_mutex); 00122 gsh_free(segment); 00123 return STATE_SUCCESS; 00124 } 00125 00126 00143 state_status_t 00144 state_lookup_layout_state(cache_entry_t * pentry, 00145 state_owner_t * powner, 00146 layouttype4 type, 00147 state_t ** pstate) 00148 { 00149 /* Pointer for iterating over the list of states on the file */ 00150 struct glist_head * glist_iter = NULL; 00151 /* The state under inspection in the loop */ 00152 state_t * pstate_iter = NULL; 00153 /* The state found, if one exists */ 00154 state_t * pstate_found = NULL; 00155 00156 glist_for_each(glist_iter, &pentry->object.file.state_list) { 00157 pstate_iter = glist_entry(glist_iter, state_t, state_list); 00158 if ((pstate_iter->state_type == STATE_TYPE_LAYOUT) && 00159 (pstate_iter->state_powner == powner) && 00160 (pstate_iter->state_data.layout.state_layout_type == type)) { 00161 pstate_found = pstate_iter; 00162 break; 00163 } 00164 } 00165 00166 if (!pstate_found) { 00167 return STATE_NOT_FOUND; 00168 } else if (pstate_found->state_pentry != pentry) { 00169 return STATE_INCONSISTENT_ENTRY; 00170 } else { 00171 *pstate = pstate_found; 00172 return STATE_SUCCESS; 00173 } 00174 }