nfs-ganesha 1.4

state_layout.c

Go to the documentation of this file.
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 }