nfs-ganesha 1.4

cache_content_crash_recover.c

Go to the documentation of this file.
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                          /* _SOLARIS */
00044 
00045 #include "LRU_List.h"
00046 #include "log.h"
00047 #include "HashData.h"
00048 #include "HashTable.h"
00049 #include "fsal.h"
00050 #include "cache_inode.h"
00051 #include "cache_content.h"
00052 
00053 #include <unistd.h>
00054 #include <sys/types.h>
00055 #include <sys/param.h>
00056 #include <time.h>
00057 #include <pthread.h>
00058 #include <errno.h>
00059 #include <dirent.h>
00060 #include <string.h>
00061 
00071 cache_content_status_t cache_content_crash_recover(unsigned short exportid,
00072                                                    unsigned int index,
00073                                                    unsigned int mod,
00074                                                    cache_content_client_t * pclient_data,
00075                                                    fsal_op_context_t * pcontext,
00076                                                    cache_content_status_t * pstatus)
00077 {
00078   DIR *cache_directory;
00079   cache_content_dirinfo_t export_directory;
00080 
00081   char cache_exportdir[MAXPATHLEN];
00082   char fullpath[MAXPATHLEN];
00083 
00084   struct dirent *direntp;
00085   struct dirent dirent_export;
00086 
00087   int found_export_id;
00088   u_int64_t inum;
00089 
00090   off_t size_in_cache;
00091 
00092   cache_entry_t inode_entry;
00093   cache_entry_t *pentry = NULL;
00094   cache_content_entry_t *pentry_content = NULL;
00095   cache_inode_status_t cache_inode_status;
00096   cache_content_status_t cache_content_status;
00097 
00098   fsal_attrib_list_t fsal_attr;
00099   cache_inode_fsal_data_t fsal_data;
00100 
00101   *pstatus = CACHE_CONTENT_SUCCESS;
00102 
00103   /* Open the cache directory */
00104   if((cache_directory = opendir(pclient_data->cache_dir)) == NULL)
00105     {
00106       *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR;
00107       return *pstatus;
00108     }
00109   /* read the cache directory */
00110   while((direntp = readdir(cache_directory)) != NULL)
00111     {
00112 
00113       /* . and .. are of no interest */
00114       if(!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, ".."))
00115         continue;
00116 
00117       if((found_export_id = cache_content_get_export_id(direntp->d_name)) >= 0)
00118         {
00119           LogEvent(COMPONENT_CACHE_CONTENT,
00120                             "Directory cache for Export ID %d has been found",
00121                             found_export_id);
00122           snprintf(cache_exportdir, MAXPATHLEN, "%s/%s", pclient_data->cache_dir,
00123                    direntp->d_name);
00124 
00125           if(cache_content_local_cache_opendir(cache_exportdir, &(export_directory)) ==
00126              FALSE)
00127             {
00128               *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR;
00129               closedir(cache_directory);
00130               return *pstatus;
00131             }
00132 
00133           /* Reads the directory content (a single thread for the moment) */
00134 
00135           while(cache_content_local_cache_dir_iter
00136                 (&export_directory, &dirent_export, index, mod))
00137             {
00138               /* . and .. are of no interest */
00139               if(!strcmp(dirent_export.d_name, ".")
00140                  || !strcmp(dirent_export.d_name, ".."))
00141                 continue;
00142 
00143               if((inum = cache_content_get_inum(dirent_export.d_name)) > 0)
00144                 {
00145                   LogEvent(COMPONENT_CACHE_CONTENT,
00146                                     "Cache entry for File ID %"PRIx64" has been found", inum);
00147 
00148                   /* Get the content of the file */
00149                   sprintf(fullpath, "%s/%s/%s", pclient_data->cache_dir, direntp->d_name,
00150                           dirent_export.d_name);
00151 
00152                   /* Populating the cache_inode... */
00153                   fsal_data.fh_desc = inode_entry.fh_desc;
00154 
00155                   if((pentry = cache_inode_get(&fsal_data,
00156                                                &fsal_attr,
00157                                                pcontext, &cache_inode_status)) == NULL)
00158                     {
00159                       LogCrit(COMPONENT_CACHE_CONTENT,
00160                                    "Error adding cached inode for file ID %"PRIx64", error=%d",
00161                                    inum, cache_inode_status);
00162                       continue;
00163                     }
00164                   else
00165                     LogEvent(COMPONENT_CACHE_CONTENT,
00166                                       "Cached inode added successfully for file ID %"PRIx64,
00167                                       inum);
00168 
00169                   /* Get the size from the cache */
00170                   if((size_in_cache =
00171                       cache_content_recover_size(cache_exportdir, inum)) == -1)
00172                     {
00173                       LogCrit(COMPONENT_CACHE_CONTENT,
00174                                    "Error when recovering size for file ID %"PRIx64, inum);
00175                     }
00176                   else
00177                     pentry->attributes.filesize = (fsal_size_t) size_in_cache;
00178 
00179                   /* Adding the cached entry to the data cache */
00180                   if((pentry_content = cache_content_new_entry(pentry,
00181                                                                NULL,
00182                                                                pclient_data,
00183                                                                RECOVER_ENTRY,
00184                                                                pcontext,
00185                                                                &cache_content_status)) ==
00186                      NULL)
00187                     {
00188                       LogCrit(COMPONENT_CACHE_CONTENT,
00189                                    "Error adding cached data for file ID %"PRIx64", error=%d",
00190                                    inum, cache_inode_status);
00191                       continue;
00192                     }
00193                   else
00194                     LogEvent(COMPONENT_CACHE_CONTENT,
00195                                       "Cached data added successfully for file ID %"PRIx64,
00196                                       inum);
00197 
00198                 }
00199 
00200             }                   /*  while( ( dirent_export = readdir( export_directory ) ) != NULL ) */
00201 
00202           /* Close the export cache directory */
00203           cache_content_local_cache_closedir(&export_directory);
00204 
00205         }                       /* if( ( found_export_id = cache_content_get_export_id( direntp->d_name ) ) > 0 ) */
00206     }                           /* while( ( direntp = readdir( cache_directory ) ) != NULL ) */
00207 
00208   /* Close the cache directory */
00209   closedir(cache_directory);
00210 
00211   return *pstatus;
00212 }                               /* cache_content_crash_recover */