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 00037 #ifdef HAVE_CONFIG_H 00038 #include "config.h" 00039 #endif 00040 00041 #ifdef _SOLARIS 00042 #include "solaris_port.h" 00043 #endif 00044 00045 #include <stdio.h> 00046 #include <string.h> 00047 #include <pthread.h> 00048 #include <fcntl.h> 00049 #include <sys/file.h> /* for having FNDELAY */ 00050 #include "HashData.h" 00051 #include "HashTable.h" 00052 #include "log.h" 00053 #include "ganesha_rpc.h" 00054 #include "nfs23.h" 00055 #include "nfs4.h" 00056 #include "mount.h" 00057 #include "nfs_core.h" 00058 #include "cache_inode.h" 00059 #include "nfs_exports.h" 00060 #include "nfs_creds.h" 00061 #include "nfs_proto_functions.h" 00062 #include "nfs_dupreq.h" 00063 #include "nfs_file_handle.h" 00064 #include "nfs_stat.h" 00065 #include "SemN.h" 00066 #include "nfs_init.h" 00067 00068 /* Structures from another module */ 00069 extern nfs_start_info_t nfs_start_info; 00070 00081 fsal_op_context_t fsal_context[NB_MAX_FLUSHER_THREAD]; 00082 00083 void *nfs_file_content_flush_thread(void *flush_data_arg) 00084 { 00085 fsal_status_t fsal_status; 00086 char cache_sub_dir[MAXPATHLEN]; 00087 cache_content_status_t content_status; 00088 nfs_flush_thread_data_t *p_flush_data = NULL; 00089 exportlist_t *pexport; 00090 char function_name[MAXNAMLEN]; 00091 #ifdef _USE_XFS 00092 xfsfsal_export_context_t export_context ; 00093 fsal_path_t export_path ; 00094 #endif 00095 00096 p_flush_data = (nfs_flush_thread_data_t *) flush_data_arg; 00097 00098 sprintf(function_name, "nfs_file_content_flush_thread #%u", p_flush_data->thread_index); 00099 00100 SetNameFunction(function_name); 00101 00102 LogDebug(COMPONENT_MAIN, 00103 "NFS DATACACHE FLUSHER THREAD #%u : Starting", 00104 p_flush_data->thread_index); 00105 00106 /* Initialisation of credential for current thread */ 00107 LogInfo(COMPONENT_MAIN, 00108 "NFS DATACACHE FLUSHER THREAD #%u : Initialization of thread's credential", 00109 p_flush_data->thread_index); 00110 if(FSAL_IS_ERROR(FSAL_InitClientContext(&(fsal_context[p_flush_data->thread_index])))) 00111 { 00112 /* Failed init */ 00113 LogFatal(COMPONENT_MAIN, 00114 "NFS DATACACHE FLUSHER THREAD #%u : Error initializing thread's credential", 00115 p_flush_data->thread_index); 00116 } 00117 00118 /* check for each pexport entry to get those who are data cached */ 00119 for(pexport = nfs_param.pexportlist; pexport != NULL; pexport = pexport->next) 00120 { 00121 00122 if(pexport->options & EXPORT_OPTION_USE_DATACACHE) 00123 { 00124 LogEvent(COMPONENT_MAIN, 00125 "Starting flush on Export Entry #%u", 00126 pexport->id); 00127 00128 fsal_status = 00129 FSAL_GetClientContext(&(fsal_context[p_flush_data->thread_index]), 00130 &pexport->FS_export_context, 0, -1, NULL, 0); 00131 00132 if(FSAL_IS_ERROR(fsal_status)) 00133 LogError(COMPONENT_MAIN, ERR_FSAL, fsal_status.major, fsal_status.minor); 00134 00135 #ifdef _USE_XFS 00136 /* This is badly, badly broken. rework export struct defs and api because 00137 * this breaks dynamic multi-fsal support */ 00138 00139 /* Export Context is required for FSAL_XFS to work properly (it set the XFS fshandle) */ 00140 fsal_status = FSAL_str2path( pexport->dirname, strlen( pexport->dirname ) , &export_path ) ; 00141 if(FSAL_IS_ERROR(fsal_status)) 00142 LogError(COMPONENT_MAIN, ERR_FSAL, fsal_status.major, fsal_status.minor); 00143 00144 strncpy( export_context.mount_point, 00145 pexport->dirname, FSAL_MAX_PATH_LEN -1 ) ; 00146 fsal_status = FSAL_BuildExportContext( &export_context, &export_path, NULL ) ; 00147 if(FSAL_IS_ERROR(fsal_status)) 00148 LogError(COMPONENT_MAIN, ERR_FSAL, fsal_status.major, fsal_status.minor); 00149 #endif 00150 /* XXX: all entries are put in the same export_id path with id=0 */ 00151 snprintf(cache_sub_dir, MAXPATHLEN, "%s/export_id=%d", 00152 nfs_param.cache_layers_param.cache_content_client_param.cache_dir, 0); 00153 00154 if(cache_content_emergency_flush(cache_sub_dir, 00155 nfs_start_info.flush_behaviour, 00156 nfs_start_info.lw_mark_trigger, 00157 nfs_param.cache_layers_param.dcgcpol.emergency_grace_delay, 00158 p_flush_data->thread_index, 00159 nfs_start_info.nb_flush_threads, 00160 &p_flush_data->nb_flushed, 00161 &p_flush_data->nb_too_young, 00162 &p_flush_data->nb_errors, 00163 &p_flush_data->nb_orphans, 00164 &(fsal_context[p_flush_data->thread_index]), 00165 &content_status) != CACHE_CONTENT_SUCCESS) 00166 { 00167 LogCrit(COMPONENT_MAIN, 00168 "Flush on Export Entry #%u failed", pexport->id); 00169 } 00170 else 00171 { 00172 LogEvent(COMPONENT_MAIN, 00173 "Flush on Export Entry #%u is ok", pexport->id); 00174 00175 /* XXX: for now, all cached data are put in the export directory (with export_id=0) 00176 * Thus, we don't need to have a flush for each export_id. 00177 * Once a flush is done for one export, we can stop. 00178 */ 00179 break; 00180 } 00181 00182 } 00183 else 00184 LogEvent(COMPONENT_MAIN, 00185 "Export Entry #%u is not data cached, skipping..", 00186 pexport->id); 00187 } 00188 00189 /* Tell the admin that flush is done */ 00190 LogEvent(COMPONENT_MAIN, 00191 "NFS DATACACHE FLUSHER THREAD #%d : flush of the data cache is done for this thread. Closing thread", 00192 p_flush_data->thread_index); 00193 00194 return NULL; 00195 } /* nfs_file_content_flush_thread */