nfs-ganesha 1.4

commands_Cache_inode.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 
00034 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037 
00038 #include "fsal.h"
00039 #include "cache_inode.h"
00040 #include "cache_inode_lru.h"
00041 #include "cache_inode_weakref.h"
00042 #include "LRU_List.h"
00043 #include "err_fsal.h"
00044 #include "err_cache_inode.h"
00045 #include "abstract_mem.h"
00046 #include "cmd_tools.h"
00047 #include "commands.h"
00048 #include "Getopt.h"
00049 
00050 #include <unistd.h>
00051 #include <stdio.h>
00052 #include <strings.h>
00053 #include <errno.h>
00054 #include <sys/types.h>
00055 #include <sys/time.h>
00056 #include <string.h>
00057 #include <sys/stat.h>
00058 #include <time.h>
00059 #include <pwd.h>
00060 #include <ctype.h>
00061 
00062 #define EXPORT_ID 1
00063 #define ATTR_LEN  100
00064 
00065 static char localmachine[256];
00066 #ifdef OLD_LOGGING
00067 static desc_log_stream_t voie_cache;
00068 static log_t log_desc_cache = LOG_INITIALIZER;
00069 #endif
00070 
00072 static cache_entry_t *pentry_root;
00073 
00074 static int cache_init = FALSE;
00075 
00077 static cache_inode_gc_policy_t gcpol;
00078 
00080 //static cache_inode_policy_t cachepol = CACHE_INODE_POLICY_FULL_WRITE_THROUGH;
00081 static cache_inode_policy_t cachepol = CACHE_INODE_POLICY_ATTRS_ONLY_WRITE_THROUGH ;
00082 
00084 cache_inode_client_parameter_t cache_client_param;
00085 cache_content_client_parameter_t datacache_client_param;
00086 
00087 typedef struct cmdCacheInode_thr_info__
00088 {
00089 
00090   int is_thread_init;
00091 
00092   /* export context : on for each thread,
00093    * on order to make it possible for them
00094    * to access different filesets.
00095    */
00096   fsal_export_context_t exp_context;
00097 
00099   fsal_op_context_t context;
00100 
00102   cache_inode_status_t cache_status;
00103 
00104   int is_client_init;
00105 
00107   cache_entry_t *pentry;
00108 
00110   char current_path[FSAL_MAX_PATH_LEN]; /* current path */
00111 
00113   cache_content_client_t dc_client;
00114 
00115 } cmdCacheInode_thr_info_t;
00116 
00117 /* pthread key to manage thread specific configuration */
00118 
00119 static pthread_key_t thread_key;
00120 static pthread_once_t once_key = PTHREAD_ONCE_INIT;
00121 
00122 /* init pthtread_key for current thread */
00123 
00124 static void init_keys(void)
00125 {
00126   if(pthread_key_create(&thread_key, NULL) == -1)
00127     printf("Error %d creating pthread key for thread %p : %s\n",
00128            errno, (caddr_t) pthread_self(), strerror(errno));
00129 
00130   return;
00131 }                               /* init_keys */
00132 
00137 static cmdCacheInode_thr_info_t *GetCacheInodeContext()
00138 {
00139   cmdCacheInode_thr_info_t *p_current_thread_vars;
00140 
00141   /* first, we init the keys if this is the first time */
00142   if(pthread_once(&once_key, init_keys) != 0)
00143     {
00144       printf("Error %d calling pthread_once for thread %p : %s\n",
00145              errno, (caddr_t) pthread_self(), strerror(errno));
00146       return NULL;
00147     }
00148 
00149   p_current_thread_vars = (cmdCacheInode_thr_info_t *) pthread_getspecific(thread_key);
00150 
00151   /* we allocate the thread context if this is the first time */
00152   if(p_current_thread_vars == NULL)
00153     {
00154 
00155       /* allocates thread structure */
00156       p_current_thread_vars
00157            = gsh_malloc(sizeof(cmdCacheInode_thr_info_t));
00158 
00159       /* panic !!! */
00160       if(p_current_thread_vars == NULL)
00161         {
00162           printf("%p:commands_Cache_inode: Not enough memory\n",
00163                  (caddr_t) pthread_self());
00164           return NULL;
00165         }
00166 
00167       /* Clean thread context */
00168 
00169       memset(p_current_thread_vars, 0, sizeof(cmdCacheInode_thr_info_t));
00170 
00171       p_current_thread_vars->is_thread_init = FALSE;
00172       p_current_thread_vars->is_client_init = FALSE;
00173       strcpy(p_current_thread_vars->current_path, "");
00174       p_current_thread_vars->pentry = NULL;
00175       p_current_thread_vars->cache_status = CACHE_INODE_SUCCESS;
00176 
00177       /* set the specific value */
00178       pthread_setspecific(thread_key, (void *)p_current_thread_vars);
00179 
00180     }
00181 
00182   return p_current_thread_vars;
00183 
00184 }                               /* GetCacheInodeContext */
00185 
00186 static int InitThread(cmdCacheInode_thr_info_t * thr_info)
00187 {
00188 
00189   uid_t uid;
00190   fsal_status_t st;
00191   struct passwd *pw_struct;
00192 
00193   /* for the moment, create export context for root fileset */
00194   st = FSAL_BuildExportContext(&thr_info->exp_context, NULL, NULL);
00195 
00196   /* initialize FSAL credential for this thread */
00197 
00198   st = FSAL_InitClientContext(&thr_info->context);
00199 
00200   if(FSAL_IS_ERROR(st))
00201     {
00202       printf
00203           ("%p:commands_Cache_inode: Error %d initializing context for thread (FSAL_InitThreadCred)\n",
00204            (caddr_t) pthread_self(), st.major);
00205       return 1;
00206     }
00207 
00208   uid = getuid();
00209 
00210   pw_struct = getpwuid(uid);
00211 
00212   if(pw_struct == NULL)
00213     {
00214       printf("commands_Cache_inode: Unknown user %u\n", uid);
00215       return 1;
00216     }
00217 
00218   st = FSAL_GetClientContext(&thr_info->context, &thr_info->exp_context,
00219                              uid, pw_struct->pw_gid, NULL, 0);
00220 
00221   if(FSAL_IS_ERROR(st))
00222     {
00223       printf
00224           ("%p:commands_Cache_inode: Error %d getting contexte for uid %d (FSAL_GetUserCred)\n",
00225            (caddr_t) pthread_self(), st.major, uid);
00226       return 1;
00227     }
00228 
00229   thr_info->is_thread_init = TRUE;
00230 
00231   return 0;
00232 
00233 }
00234 
00235 static int InitClient(cmdCacheInode_thr_info_t * thr_info)
00236 {
00237   thr_info->pentry = pentry_root;
00238 
00239   strcpy(thr_info->current_path, "/");
00240 
00241   /* Init the cache_inode client */
00242   if(cache_inode_client_init(&thr_info->client, &cache_client_param, 0, NULL) != 0)
00243     return 1;
00244 
00245   /* Init the cache content client */
00246   if(cache_content_client_init(&thr_info->dc_client, datacache_client_param, "") != 0)
00247     return 1;
00248 
00249   thr_info->client.pcontent_client = (caddr_t) & thr_info->dc_client;
00250 
00251   thr_info->is_client_init = TRUE;
00252 
00253   return 0;
00254 
00255 }
00256 
00257 cmdCacheInode_thr_info_t *RetrieveInitializedContext()
00258 {
00259 
00260   cmdCacheInode_thr_info_t *context;
00261 
00262   context = GetCacheInodeContext();
00263 
00264   if(context->is_thread_init != TRUE)
00265     if(InitThread(context))
00266       {
00267         printf("Error occured during thread initialization.\n");
00268         return NULL;
00269       }
00270 
00271   if(context->is_client_init != TRUE)
00272     if(InitClient(context))
00273       {
00274         printf("Error occured during client initialization.\n");
00275         return NULL;
00276       }
00277 
00278   return context;
00279 
00280 }
00281 
00282 void Cache_inode_layer_SetLogLevel(int log_lvl)
00283 {
00284 #ifdef OLD_LOGGING
00285   log_stream_t *curr;
00286 
00287   /* mutex pour proteger le descriptor de log */
00288   pthread_mutex_lock(&mutex_log);
00289 
00290   /* first time */
00291   if(log_level == -1)
00292     {
00293       log_level = log_lvl;
00294       voie_cache.fd = fileno(stderr);
00295       AddLogStreamJd(&log_desc_cache, V_FD, voie_cache, log_level, SUP);
00296     }
00297   else
00298     {
00299       log_level = log_lvl;
00300       /* changing log level */
00301       curr = log_desc_cache.liste_voies;
00302       while(curr)
00303         {
00304           curr->niveau = log_level;
00305           curr = curr->suivante;
00306         }
00307     }
00308 
00309   /* mutex pour proteger le descriptor de log */
00310   pthread_mutex_unlock(&mutex_log);
00311 #endif
00312 }
00313 
00314 int lru_entry_to_str(LRU_data_t data, char *str)
00315 {
00316   return sprintf(str, "%p (len=%llu)", data.pdata, (unsigned long long)data.len);
00317 }                               /* lru_entry_to_str */
00318 
00319 int lru_clean_entry(LRU_entry_t * entry, void *adddata)
00320 {
00321   return 0;
00322 }                               /* lru_clean_entry */
00323 
00324 static void getopt_init()
00325 {
00326   /* disables getopt error message */
00327   Opterr = 0;
00328 
00329   /* reinits getopt processing */
00330   Optind = 1;
00331 
00332 }
00333 
00334 /* solves a relative or aboslute path */
00335 int cache_solvepath(char *io_global_path, int size_global_path, /* global path */
00336                     char *i_spec_path,  /* specified path */
00337                     cache_entry_t * current_pentry,     /* current directory handle */
00338                     cache_entry_t ** pnew_pentry, FILE * output)
00339 {
00340   char str_path[FSAL_MAX_PATH_LEN];
00341 
00342   fsal_name_t name;
00343   fsal_status_t st;
00344   char tmp_path[FSAL_MAX_PATH_LEN];
00345   char *next_name;
00346   char *curr;
00347   int last = 0;
00348 
00349   cache_inode_fsal_data_t fsdata;
00350 
00351   cache_entry_t *pentry_lookup = NULL;
00352   cache_entry_t *pentry_tmp = NULL;
00353   fsal_attrib_list_t attrlookup;
00354 
00355   cmdCacheInode_thr_info_t *context;
00356   context = RetrieveInitializedContext();
00357 
00358   /* is it a relative or an absolute path ? */
00359   strncpy(str_path, i_spec_path, FSAL_MAX_PATH_LEN);
00360   str_path[FSAL_MAX_PATH_LEN - 1] = '\0';
00361 
00362   curr = str_path;
00363   next_name = str_path;
00364 
00365   if(str_path[0] == '@')
00366     {
00367       /* It is a file handle */
00368       int rc;
00369 
00370 /*FIXME: this probably won't work with sized handle and no fh_desc.len */
00371       rc = sscanHandle(fsdata.fh_desc.start, str_path + 1);
00372 
00373       if(rc <= 0)
00374         {
00375           fprintf(output, "Invalid FileHandle: %s\n", str_path);
00376           return -1;
00377         }
00378 
00379       if(str_path[rc + 1] != '\0')
00380         {
00381           fprintf(output, "Invalid FileHandle: %s\n", str_path);
00382           return -1;
00383         }
00384 
00385       /* Get the corresponding pentry */
00386       fsdata.fh_desc.len = 0;
00387       (void) FSAL_ExpandHandle(NULL,
00388                                FSAL_DIGEST_SIZEOF,
00389                                &fsdata.fh_desc);
00390 
00391       if((pentry_tmp = cache_inode_get(&fsdata,
00392                                        cachepol,
00393                                        &attrlookup,
00394                                        &context->client,
00395                                        &context->context,
00396                                        &context->cache_status)) == NULL)
00397         {
00398           log_fprintf(output, "Error executing cache_inode_get( \"%s\" ) : %J%r\n",
00399                       str_path, ERR_CACHE_INODE, context->cache_status);
00400 
00401           return context->cache_status;
00402         }
00403 
00404       strncpy(io_global_path, str_path, size_global_path);
00405       io_global_path[size_global_path - 1] = '\0';
00406       *pnew_pentry = pentry_tmp;
00407 
00408       return 0;
00409 
00410     }
00411   else if(str_path[0] == '/')
00412     {
00413       /* absolute path, starting from "/", with a relative path */
00414       curr++;
00415       next_name++;
00416       pentry_lookup = pentry_root;
00417       strncpy(tmp_path, "/", FSAL_MAX_PATH_LEN);
00418 
00419       /* the the directory  is /, return */
00420       if(str_path[1] == '\0')
00421         {
00422           strncpy(io_global_path, tmp_path, size_global_path);
00423           *pnew_pentry = pentry_lookup;
00424           return 0;
00425         }
00426 
00427     }
00428   else
00429     {
00430       pentry_lookup = current_pentry;
00431       strncpy(tmp_path, io_global_path, FSAL_MAX_PATH_LEN);
00432     }
00433 
00434   /* Now, the path is a relative path, proceed a step by step lookup */
00435   do
00436     {
00437 
00438       /* tokenize to the next '/' */
00439       while((curr[0] != '\0') && (curr[0] != '/'))
00440         curr++;
00441 
00442       if(!curr[0])
00443         last = 1;               /* remembers if it was the last dir */
00444 
00445       curr[0] = '\0';
00446 
00447       /* build the name */
00448       if(FSAL_IS_ERROR(st = FSAL_str2name(next_name, FSAL_MAX_PATH_LEN, &name)))
00449         {
00450           fprintf(output, "Error executing FSAL_str2name:");
00451           print_fsal_status(output, st);
00452           fprintf(output, "\n");
00453           return st.major;
00454         }
00455 
00456       /* lookup this name */
00457 
00458       if((pentry_tmp = cache_inode_lookup(pentry_lookup,
00459                                           &name,
00460                                           cachepol,
00461                                           &attrlookup,
00462                                           &context->client,
00463                                           &context->context,
00464                                           &context->cache_status)) == NULL)
00465         {
00466           log_fprintf(output,
00467                       "Error executing cache_inode_lookup( \"%s\", \"%s\" ) : %J%r\n",
00468                       tmp_path, name.name, ERR_CACHE_INODE, context->cache_status);
00469 
00470           return context->cache_status;
00471         }
00472 
00473       /* updates current handle */
00474       pentry_lookup = pentry_tmp;
00475 
00476       /* adds /name at the end of the path */
00477       strncat(tmp_path, "/", FSAL_MAX_PATH_LEN);
00478       strncat(tmp_path, next_name, FSAL_MAX_PATH_LEN - strlen(tmp_path));
00479 
00480       /* updates cursors */
00481       if(!last)
00482         {
00483           curr++;
00484           next_name = curr;
00485           /* ignore successive slashes */
00486           while((curr[0] != '\0') && (curr[0] == '/'))
00487             {
00488               curr++;
00489               next_name = curr;
00490             }
00491           if(!curr[0])
00492             last = 1;           /* it is the last dir */
00493         }
00494 
00495     }
00496   while(!last);
00497 
00498   /* everything is OK, apply changes */
00499   clean_path(tmp_path, size_global_path);
00500   strncpy(io_global_path, tmp_path, size_global_path);
00501 
00502   *pnew_pentry = pentry_lookup;
00503   return 0;
00504 
00505 }
00506 
00507 int cacheinode_init(char *filename, int flag_v, FILE * output)
00508 {
00509   int rc;
00510 
00511   fsal_status_t status;
00512   fsal_path_t __attribute__ ((__unused__)) pathroot;
00513   fsal_handle_t root_handle;
00514   fsal_attrib_list_t attrs;
00515 
00516   cache_inode_fsal_data_t fsdata;
00517   cache_inode_parameter_t cache_param;
00518   config_file_t config_file;
00519 
00520   cmdCacheInode_thr_info_t *context;
00521 
00522   /* geting the hostname */
00523   if(gethostname(localmachine, sizeof(localmachine)) != 0)
00524     {
00525       fprintf(stderr, "Error in gethostname is %s", strerror(errno));
00526       exit(1);
00527     }
00528   else
00529     SetNameHost(localmachine);
00530 
00531   /* Parse config file */
00532   if((config_file = config_ParseFile(filename)) == NULL)
00533     {
00534       fprintf(output, "init_cache: Error parsing %s: %s\n", filename,
00535               config_GetErrorMsg());
00536       return -1;
00537     }
00538 
00539   /* creating log */
00540   AddFamilyError(ERR_CACHE_INODE, "Cache_inode related Errors",
00541                  tab_errstatus_cache_inode);
00542 
00543   /* creates thread context */
00544 
00545   context = GetCacheInodeContext();
00546 
00547   if(context->is_thread_init != TRUE)
00548     if(InitThread(context))
00549       {
00550         fprintf(output, "Error ossured during thread initialization.\n");
00551         return 1;
00552       }
00553 
00554   /* Reading the hash parameter */
00555   rc = cache_inode_read_conf_hash_parameter(config_file, &cache_param);
00556   if(rc != CACHE_INODE_SUCCESS)
00557     {
00558       log_fprintf(output, "Error executing cache_inode_read_conf_hash_parameter : %J%r\n",
00559                   ERR_CACHE_INODE, rc);
00560 
00561       return 1;
00562     }
00563 
00564   cache_param.hparam.hash_func_key = cache_inode_fsal_hash_func;
00565 
00566   cache_param.hparam.hash_func_rbt = cache_inode_fsal_rbt_func;
00567   cache_param.hparam.hash_func_both = NULL ; /* BUGAZOMEU */
00568   cache_param.hparam.compare_key = cache_inode_compare_key_fsal;
00569   cache_param.hparam.key_to_str = NULL;
00570   cache_param.hparam.val_to_str = NULL;
00571   cache_param.hparam.ht_name = "Cache Inode";
00572   cache_param.hparam.flags = HT_FLAG_CACHE;
00573   cache_param.hparam.ht_log_component = COMPONENT_CACHE_INODE;
00574 
00575   if(flag_v)
00576     cache_inode_print_conf_hash_parameter(output, cache_param);
00577 
00578   if((fh_to_cache_entry_ht = cache_inode_init(cache_param, &context->cache_status)) == NULL)
00579     {
00580       fprintf(output, "Error %d while init hash\n ", context->cache_status);
00581       return 1;
00582     }
00583   else if(flag_v)
00584     fprintf(output, "\tHash Table address = %p\n",
00585             fh_to_cache_entry_ht);
00586 
00587   /* Get the gc policy */
00588   rc = cache_inode_read_conf_gc_policy(config_file, &gcpol);
00589   if(rc != CACHE_INODE_SUCCESS)
00590     {
00591       log_fprintf(output, "Error executing cache_inode_read_conf_gc_policy : %J%r\n",
00592                   ERR_CACHE_INODE, rc);
00593       return 1;
00594     }
00595 
00596   if(flag_v)
00597     cache_inode_print_conf_gc_policy(output, gcpol);
00598 
00599   /* retrieve lower layer info */
00600 
00601   /* Getting the root of the FS */
00602 #if defined( _USE_PROXY )
00603   /*if( FSAL_IS_ERROR( status = FSAL_str2path( "/users/thomas/./", FSAL_MAX_PATH_LEN, &pathroot ) ) ) */
00604   if(FSAL_IS_ERROR(status = FSAL_str2path("/", FSAL_MAX_PATH_LEN, &pathroot)))
00605     {
00606       char buffer[LOG_MAX_STRLEN];
00607 
00608       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00609       fprintf(output, "%s\n", buffer);
00610       return 1;
00611     }
00612 
00613   if(FSAL_IS_ERROR
00614      (status = FSAL_lookupPath(&pathroot, &context->context, &root_handle, NULL)))
00615     {
00616       char buffer[LOG_MAX_STRLEN];
00617 
00618       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00619       fprintf(output, "%s\n", buffer);
00620       return 1;
00621     }
00622 #elif defined( _USE_VFS )
00623 if(FSAL_IS_ERROR(status = FSAL_str2path("/tmp", FSAL_MAX_PATH_LEN, &pathroot)))
00624     {
00625       char buffer[LOG_MAX_STRLEN];
00626 
00627       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00628       fprintf(output, "%s\n", buffer);
00629       return 1;
00630     }
00631 
00632   if(FSAL_IS_ERROR
00633      (status = FSAL_lookupPath(&pathroot, &context->context, &root_handle, NULL)))
00634     {
00635       char buffer[LOG_MAX_STRLEN];
00636 
00637       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00638       fprintf(output, "%s\n", buffer);
00639       return 1;
00640     }
00641 #elif defined( _USE_XFS )
00642 if(FSAL_IS_ERROR(status = FSAL_str2path("/xfs", FSAL_MAX_PATH_LEN, &pathroot)))
00643     {
00644       char buffer[LOG_MAX_STRLEN];
00645 
00646       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00647       fprintf(output, "%s\n", buffer);
00648       return 1;
00649     }
00650 
00651   if(FSAL_IS_ERROR
00652      (status = FSAL_lookupPath(&pathroot, &context->context, &root_handle, NULL)))
00653     {
00654       char buffer[LOG_MAX_STRLEN];
00655 
00656       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00657       fprintf(output, "%s\n", buffer);
00658       return 1;
00659     }
00660 #else
00661   if(FSAL_IS_ERROR
00662      (status = FSAL_lookup(NULL, NULL, &context->context, &root_handle, NULL)))
00663     {
00664       char buffer[LOG_MAX_STRLEN];
00665 
00666       MakeLogError(buffer, ERR_FSAL, status.major, status.minor, __LINE__);
00667       fprintf(output, "%s\n", buffer);
00668       return 1;
00669     }
00670 #endif
00671 
00672   /* retrieve supported attributes */
00673 
00674   FSAL_CLEAR_MASK(attrs.asked_attributes);
00675   FSAL_SET_MASK(attrs.asked_attributes, FSAL_ATTR_SUPPATTR);
00676   if(FSAL_IS_ERROR(status = FSAL_getattrs(&root_handle, &context->context, &attrs)))
00677     {
00678       fprintf(output, "Error executing FSAL_getattrs:");
00679       print_fsal_status(output, status);
00680       fprintf(output, "\n");
00681       return status.major;
00682     }
00683 
00684 #ifdef OLD_LOGGING
00685   cache_client_param.log_outputs = log_desc_cache;
00686 #endif
00687   cache_client_param.attrmask = attrs.supported_attributes;
00688 
00689   /* We need a cache_client to acces the cache */
00690   rc = cache_inode_read_conf_client_parameter(config_file, &cache_client_param);
00691   if(rc != CACHE_INODE_SUCCESS)
00692     {
00693       log_fprintf(output,
00694                   "Error executing cache_inode_read_conf_client_parameter : %J%r\n",
00695                   ERR_CACHE_INODE, rc);
00696       return 1;
00697     }
00698 
00699   /* We need a cache_client to acces the datacache */
00700   rc = cache_content_read_conf_client_parameter(config_file, &datacache_client_param);
00701   if(rc != CACHE_CONTENT_SUCCESS)
00702     {
00703       log_fprintf(output,
00704                   "Error executing cache_content_read_conf_client_parameter : %J%r\n",
00705                   ERR_CACHE_INODE, rc);
00706       return 1;
00707     }
00708 #ifdef OLD_LOGGING
00709   datacache_client_param.log_outputs = log_desc_cache;
00710 #endif
00711 /*
00712   DEPRECATED :
00713   datacache_client_param.lru_param.entry_to_str = lru_entry_to_str ;
00714   datacache_client_param.lru_param.clean_entry = lru_clean_entry ;
00715 */
00716   if(flag_v)
00717     {
00718 
00719       cache_inode_print_conf_client_parameter(output, cache_client_param);
00720       cache_content_print_conf_client_parameter(output, datacache_client_param);
00721     }
00722 
00723   /* Reading the datacache core parameter */
00724   if(rc != CACHE_INODE_SUCCESS)
00725     {
00726       log_fprintf(output,
00727                   "Error executing cache_content_read_conf_core_parameter : %J%r\n",
00728                   ERR_CACHE_INODE, rc);
00729       return 1;
00730     }
00731 
00732   /* Init the cache_inode client */
00733   if(cache_inode_client_init(&context->client, &cache_client_param, 0, NULL) != 0)
00734     return 1;
00735 
00736 #ifdef _USE_ASYNC_CACHE_INODE
00737   /* Start the TAD and synclets for writeback cache inode */
00738   cache_inode_async_init(cache_client_param);
00739 
00740   if(cache_inode_async_precreate_object
00741      (&context->client, DIRECTORY, &context->exp_context) == -1)
00742     {
00743       fprintf(stderr, "NFS INIT: /!\\ Impossible to pre-create asynchronous direcory pool");
00744       exit(1);
00745     }
00746 
00747   if(cache_inode_async_precreate_object
00748      (&context->client, REGULAR_FILE, &context->exp_context) == -1)
00749     {
00750       fprintf(stderr, "NFS INIT: /!\\ Impossible to pre-create asynchronous file pool");
00751       exit(1);
00752     }
00753 #endif
00754 
00755   /* Init the cache content client */
00756   if(cache_content_client_init(&context->dc_client, datacache_client_param, "") != 0)
00757     return 1;
00758 
00759   context->client.pcontent_client = (caddr_t) & context->dc_client;
00760 
00761   fsdata.fh_desc.len = 0;
00762   fsdata.fh_desc.start = (caddr_t) &root_handle;
00763   (void) FSAL_ExpandHandle(&context->exp_context,
00764                            FSAL_DIGEST_SIZEOF,
00765                            &fsdata.fh_desc);
00766 
00767   if((context->pentry = cache_inode_make_root(&fsdata,
00768                                               cachepol,
00769                                               &context->client,
00770                                               &context->context,
00771                                               &context->cache_status)) == NULL)
00772     {
00773       fprintf(output, "Error: can't init fs's root");
00774       return 1;
00775     }
00776 
00777   if(cache_content_init_dir(datacache_client_param, EXPORT_ID) != 0)
00778     {
00779       fprintf(output, "Error: can't init datacache directory");
00780       return 1;
00781     }
00782 
00783   strcpy(context->current_path, "/");
00784 
00785   context->is_client_init = TRUE;
00786 
00787   pentry_root = context->pentry;
00788 
00789   if(flag_v)
00790     fprintf(output, "\tCache_inode successfully initialized.\n");
00791 
00792   cache_init = TRUE;
00793 
00794   /* Free config struct */
00795   config_Free(config_file);
00796 
00797   return 0;
00798 }
00799 
00801 int fn_Cache_inode_cache_init(int argc, /* IN : number of args in argv */
00802                               char **argv,      /* IN : arg list               */
00803                               FILE * output)    /* IN : output stream          */
00804 {
00805   int rc;
00806 
00807   int flag_v = 0;
00808   int flag_h = 0;
00809   int err_flag = 0;
00810   int option;
00811   char *filename = NULL;
00812 
00813   char format[] = "hv";
00814 
00815   const char help_init[] =
00816       "usage: init_cache [options] <ganesha_config_file>\n"
00817       "options :\n" "\t-h print this help\n" "\t-v verbose mode\n";
00818 
00819   if(fh_to_cache_entry_ht != NULL)
00820     {
00821       fprintf(output, "\tCache_inode is already initialized\n");
00822       return 0;
00823     }
00824 
00825   /* analysing options */
00826   getopt_init();
00827   while((option = Getopt(argc, argv, format)) != -1)
00828     {
00829       switch (option)
00830         {
00831         case 'v':
00832           if(flag_v)
00833             fprintf(output,
00834                     "init_cache: warning: option 'v' has been specified more than once.\n");
00835           else
00836             flag_v++;
00837           break;
00838 
00839         case 'h':
00840           if(flag_h)
00841             fprintf(output,
00842                     "init_cache: warning: option 'h' has been specified more than once.\n");
00843           else
00844             flag_h++;
00845           break;
00846 
00847         case '?':
00848           fprintf(output, "init_fs: unknown option : %c\n", Optopt);
00849           err_flag++;
00850           break;
00851         }                       /* switch */
00852     }                           /* while */
00853 
00854   if(flag_h)
00855     {
00856       fprintf(output, help_init);
00857       return 0;
00858     }
00859 
00860   /* verifies mandatory argument */
00861   if(Optind != (argc - 1))
00862     {
00863       /* too much or not enough arguments */
00864       err_flag++;
00865     }
00866   else
00867     filename = argv[Optind];
00868 
00869   if(err_flag)
00870     {
00871       fprintf(output, help_init);
00872       return -1;
00873     }
00874 
00875   rc = cacheinode_init(filename, flag_v, output);
00876 
00877   return rc;
00878 }
00879 
00881 int fn_Cache_inode_pwd(int argc,        /* IN : number of args in argv */
00882                        char **argv,     /* IN : arg list               */
00883                        FILE * output)   /* IN : output stream          */
00884 {
00885   fsal_handle_t *pfsal_handle = NULL;
00886   char buff[128];
00887 
00888   cmdCacheInode_thr_info_t *context;
00889   context = RetrieveInitializedContext();
00890 
00891   if(!cache_init)
00892     {
00893       fprintf(output, "Error: Cache is not initialized\n");
00894       return -1;
00895     }
00896 
00897   pfsal_handle = &context->pentry->handle;
00898 
00899   fprintf(output, "Current directory is \"%s\" \n", context->current_path);
00900   snprintmem(buff, 128, (caddr_t) pfsal_handle, sizeof(fsal_handle_t));
00901   fprintf(output, "Current File handle is \"@%s\" \n", buff);
00902 
00903   return 0;
00904 
00905 }
00906 
00908 int fn_Cache_inode_cd(int argc, /* IN : number of args in argv */
00909                       char **argv,      /* IN : arg list               */
00910                       FILE * output)    /* IN : output stream          */
00911 {
00912   char glob_path[FSAL_MAX_PATH_LEN];
00913 
00914   cache_entry_t *new_pentry;
00915   int rc;
00916 
00917   cmdCacheInode_thr_info_t *context;
00918 
00919   const char help_cd[] = "usage: cd <path>\n";
00920 
00921   if(!cache_init)
00922     {
00923       fprintf(output, "\tCache is not initialized\n");
00924       return -1;
00925     }
00926 
00927   /* Exactly one arg expected */
00928   if(argc != 2)
00929     {
00930       fprintf(output, help_cd);
00931       return -1;
00932     }
00933 
00934   context = RetrieveInitializedContext();
00935 
00936   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
00937 
00938   if((rc =
00939       cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, argv[1], context->pentry,
00940                       &new_pentry, output)) != 0)
00941     return rc;
00942 
00943   if(new_pentry->type != DIRECTORY)
00944     {
00945       fprintf(output, "Error: %s is not a directory\n", glob_path);
00946       return ENOTDIR;
00947     }
00948 
00949   if((context->cache_status = cache_inode_access(new_pentry,
00950                                                  FSAL_X_OK,
00951                                                  &context->client,
00952                                                  &context->context,
00953                                                  &context->cache_status)) !=
00954      CACHE_INODE_SUCCESS)
00955     {
00956       log_fprintf(output, "Error executing cache_inode_access : %J%r\n",
00957                   ERR_CACHE_INODE, context->cache_status);
00958       return context->cache_status;
00959     }
00960 
00961   /* if so, apply changes */
00962   strncpy(context->current_path, glob_path, FSAL_MAX_PATH_LEN);
00963   context->pentry = new_pentry;
00964 
00965   fprintf(output, "Current directory is \"%s\"\n", context->current_path);
00966 
00967   return 0;
00968 }
00969 
00971 int fn_Cache_inode_stat(int argc,       /* IN : number of args in argv */
00972                         char **argv,    /* IN : arg list               */
00973                         FILE * output)  /* IN : output stream          */
00974 {
00975   char format[] = "hv";
00976 
00977   const char help_stat[] = "usage: stat [-h][-v] <file>\n";
00978 
00979   char glob_path[FSAL_MAX_PATH_LEN];
00980   cache_entry_t *pentry_stat = NULL;
00981   fsal_attrib_list_t attrs;
00982 
00983   cmdCacheInode_thr_info_t *context;
00984 
00985   int rc, option;
00986   int flag_v = 0;
00987   int flag_h = 0;
00988   int err_flag = 0;
00989   char *file = NULL;
00990 
00991   if(!cache_init)
00992     {
00993       fprintf(output, "\tCache_inode is not initialized\n");
00994       return -1;
00995     }
00996 
00997   context = RetrieveInitializedContext();
00998 
00999   /* analysing options */
01000   getopt_init();
01001 
01002   while((option = Getopt(argc, argv, format)) != -1)
01003     {
01004 
01005       switch (option)
01006         {
01007         case 'v':
01008           if(flag_v)
01009             fprintf(output,
01010                     "stat: warning: option 'v' has been specified more than once.\n");
01011           else
01012             flag_v++;
01013           break;
01014         case 'h':
01015           if(flag_h)
01016             fprintf(output,
01017                     "stat: warning: option 'h' has been specified more than once.\n");
01018           else
01019             flag_h++;
01020           break;
01021         case '?':
01022           fprintf(output, "stat: unknown option : %c\n", Optopt);
01023           err_flag++;
01024           break;
01025         }
01026     }
01027 
01028   /* Exactly one arg expected */
01029   if(Optind != (argc - 1))
01030     {
01031       err_flag++;
01032     }
01033   else
01034     {
01035       file = argv[Optind];
01036     }
01037 
01038   if(err_flag)
01039     {
01040       fprintf(output, help_stat);
01041       return -1;
01042     }
01043 
01044   /* copy current path. */
01045   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
01046 
01047   /* retrieves object handle */
01048   if((rc = cache_solvepath(glob_path,
01049                            FSAL_MAX_PATH_LEN, file, context->pentry, &pentry_stat, output)))
01050     return rc;
01051 
01052   /* Get the attributes */
01053   if(cache_inode_getattr(pentry_stat,
01054                          &attrs,
01055                          &context->client,
01056                          &context->context,
01057                          &context->cache_status) != CACHE_INODE_SUCCESS)
01058     {
01059       log_fprintf(output, "Error executing cache_inode_getattr( \"%s\" ) : %J%r\n",
01060                   file, ERR_CACHE_INODE, context->cache_status);
01061 
01062       return context->cache_status;
01063     }
01064 
01065   /* print file attributes */
01066   print_fsal_attributes(attrs, output);
01067 
01068   return 0;
01069 }
01070 
01072 int fn_Cache_inode_gc(int argc, /* IN : number of args in argv */
01073                       char **argv,      /* IN : arg list               */
01074                       FILE * output)    /* IN : output stream          */
01075 {
01076   char format[] = "hv";
01077 
01078   const char help_gc[] = "usage: gc \n"
01079       "options :\n"
01080       "\t-h print this help\n"
01081       "   The gc policy used is defined in the configuration file\n";
01082 
01083   int option;
01084   int flag_v = 0;
01085   int flag_h = 0;
01086   int err_flag = 0;
01087 
01088   cmdCacheInode_thr_info_t *context __attribute__((unused));
01089 
01090   /* is the fs initialized ? */
01091   if(!cache_init)
01092     {
01093       fprintf(output, "Error: Cache is not initialized\n");
01094       return -1;
01095     }
01096 
01097   context = RetrieveInitializedContext();
01098 
01099   /* analysing options */
01100   getopt_init();
01101 
01102   while((option = Getopt(argc, argv, format)) != -1)
01103     {
01104       switch (option)
01105         {
01106         case 'v':
01107           if(flag_v)
01108             fprintf(output,
01109                     "ls: warning: option 'v' has been specified more than once.\n");
01110           else
01111             flag_v++;
01112           break;
01113 
01114         case 'h':
01115           if(flag_h)
01116             fprintf(output,
01117                     "ls: warning: option 'h' has been specified more than once.\n");
01118           else
01119             flag_h++;
01120           break;
01121 
01122         case '?':
01123           fprintf(output, "ls: unknown option : %c\n", Optopt);
01124           err_flag++;
01125           break;
01126         }
01127     }                           /* while */
01128 
01129   if(flag_h)
01130     {
01131       fprintf(output, help_gc);
01132       return 0;
01133     }
01134 
01135   if(err_flag)
01136     {
01137       fprintf(output, help_gc);
01138       return -1;
01139     }
01140 
01141   cache_inode_set_gc_policy(gcpol);
01142 
01143   return 0;
01144 }                               /* fn_Cache_inode_gc */
01145 
01147 int fn_Cache_inode_ls(int argc, /* IN : number of args in argv */
01148                       char **argv,      /* IN : arg list               */
01149                       FILE * output)    /* IN : output stream          */
01150 {
01151 #define CACHE_INODE_SHELL_READDIR_SIZE 10
01152   uint64_t begin_cookie = 0;
01153   uint64_t end_cookie = 0;
01154   unsigned long nbfound;
01155   cache_inode_dir_entry_t * dirent_array[CACHE_INODE_SHELL_READDIR_SIZE] ;
01156   cache_inode_endofdir_t eod_met;
01157   unsigned int i;
01158   fsal_path_t symlink_path;
01159   fsal_attrib_list_t attrs;
01160   char *str_name = ".";
01161   char item_path[FSAL_MAX_PATH_LEN];
01162   cache_entry_t *pentry_tmp = NULL;
01163 
01164   int rc = 0;
01165   char glob_path[FSAL_MAX_PATH_LEN];
01166   fsal_handle_t *pfsal_handle = NULL;
01167 
01168   char format[] = "hvdlLSHz";
01169   const char help_ls[] = "usage: ls [options]\n"
01170       "options :\n"
01171       "\t-h print this help\n"
01172       "\t-v verbose mode\n"
01173       "\t-d print directory info instead of listing its content\n"
01174       "\t-l print standard UNIX attributes\n"
01175       "\t-L print the cache_inode entry addresses\n"
01176       "\t-S print all supported attributes\n"
01177       "\t-H print the fsal handle\n" "\t-z silent mode (print nothing)\n";
01178 
01179   int option;
01180   int flag_v = 0;
01181   int flag_h = 0;
01182   int flag_d = 0;
01183   int flag_l = 0;
01184   int flag_S = 0;
01185   int flag_L = 0;
01186   int flag_H = 0;
01187   int flag_z = 0;
01188   int err_flag = 0;
01189 
01190   cmdCacheInode_thr_info_t *context;
01191 
01192   /* is the fs initialized ? */
01193   if(!cache_init)
01194     {
01195       fprintf(output, "Error: Cache is not initialized\n");
01196       return -1;
01197     }
01198 
01199   context = RetrieveInitializedContext();
01200 
01201   /* analysing options */
01202   getopt_init();
01203 
01204   while((option = Getopt(argc, argv, format)) != -1)
01205     {
01206       switch (option)
01207         {
01208         case 'v':
01209           if(flag_v)
01210             fprintf(output,
01211                     "ls: warning: option 'v' has been specified more than once.\n");
01212           else
01213             flag_v++;
01214           break;
01215 
01216         case 'h':
01217           if(flag_h)
01218             fprintf(output,
01219                     "ls: warning: option 'h' has been specified more than once.\n");
01220           else
01221             flag_h++;
01222           break;
01223 
01224         case 'd':
01225           if(flag_d)
01226             fprintf(output,
01227                     "ls: warning: option 'd' has been specified more than once.\n");
01228           else
01229             flag_d++;
01230           break;
01231 
01232         case 'l':
01233           if(flag_l)
01234             fprintf(output,
01235                     "ls: warning: option 'l' has been specified more than once.\n");
01236           else
01237             flag_l++;
01238           break;
01239 
01240         case 'L':
01241           if(flag_L)
01242             fprintf(output,
01243                     "ls: warning: option 'L' has been specified more than once.\n");
01244           else
01245             flag_L++;
01246           break;
01247 
01248         case 'S':
01249           if(flag_S)
01250             fprintf(output,
01251                     "ls: warning: option 'S' has been specified more than once.\n");
01252           else
01253             flag_S++;
01254           break;
01255 
01256         case 'z':
01257           if(flag_z)
01258             fprintf(output,
01259                     "ls: warning: option 'z' has been specified more than once.\n");
01260           else
01261             flag_z++;
01262           break;
01263 
01264         case 'H':
01265           if(flag_H)
01266             fprintf(output,
01267                     "ls: warning: option 'H' has been specified more than once.\n");
01268           else
01269             flag_H++;
01270           break;
01271 
01272         case '?':
01273           fprintf(output, "ls: unknown option : %c\n", Optopt);
01274           err_flag++;
01275           break;
01276         }
01277     }                           /* while */
01278 
01279   if(flag_l + flag_S + flag_L + flag_H > 1)
01280     {
01281       fprintf(output, "ls: conflict between options l,S,L\n");
01282       err_flag++;
01283     }
01284 
01285   if(flag_z + flag_v > 1)
01286     {
01287       fprintf(output, "ls: can't use -z and -v at the same time\n");
01288       err_flag++;
01289     }
01290 
01291   if(flag_h)
01292     {
01293       fprintf(output, help_ls);
01294       return 0;
01295     }
01296 
01297   if(err_flag)
01298     {
01299       fprintf(output, help_ls);
01300       return -1;
01301     }
01302 
01303   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
01304 
01305   /* first, retrieve the argument (if any) */
01306   if(Optind == argc - 1)
01307     {
01308       str_name = argv[Optind];
01309 
01310       /* retrieving handle */
01311       if((rc = cache_solvepath(glob_path,
01312                               FSAL_MAX_PATH_LEN,
01313                                str_name, context->pentry, &pentry_tmp, output)))
01314         return rc;
01315 
01316     }
01317   else
01318     {
01319       str_name = ".";
01320       pentry_tmp = context->pentry;
01321     }
01322 
01323   if(flag_v)
01324     fprintf(output, "proceeding ls (via Cache_inode) on \"%s\"\n", glob_path);
01325 
01326   /*
01327    * if the object is a file or a directoy with the -d option specified,
01328    * we only show its info and exit.
01329    */
01330   if((pentry_tmp->type != DIRECTORY) || flag_d)
01331     {
01332       if(pentry_tmp->type == SYMBOLIC_LINK)
01333         {
01334           if(cache_inode_readlink(pentry_tmp,
01335                                   &symlink_path,
01336                                   &context->client,
01337                                   &context->context,
01338                                   &context->cache_status) != CACHE_INODE_SUCCESS)
01339             {
01340               if(!flag_z)
01341                 log_fprintf(output, "Error executing cache_inode_readlink : %J%r\n",
01342                             ERR_CACHE_INODE, context->cache_status);
01343 
01344               return context->cache_status;
01345             }
01346         }
01347 
01348       if(cache_inode_getattr(pentry_tmp,
01349                              &attrs,
01350                              &context->client,
01351                              &context->context,
01352                              &context->cache_status) != CACHE_INODE_SUCCESS)
01353         {
01354           if(!flag_z)
01355             log_fprintf(output, "Error executing cache_inode_getattr : %J%r\n",
01356                         ERR_CACHE_INODE, context->cache_status);
01357 
01358           return context->cache_status;
01359         }
01360 
01361       if(flag_l)
01362         {
01363           if(!flag_z)
01364             print_item_line(output, &attrs, str_name, symlink_path.path);
01365         }
01366       else if(flag_S)
01367         {
01368           if(!flag_z)
01369             {
01370               fprintf(output, "%s :\n", str_name);
01371               print_fsal_attributes(attrs, output);
01372             }
01373         }
01374       else if(flag_H)
01375         {
01376           if(!flag_z)
01377             {
01378               char buff[128];
01379 
01380               pfsal_handle = &pentry_tmp->handle;
01381               snprintmem(buff, 128, (caddr_t) pfsal_handle, sizeof(fsal_handle_t));
01382               fprintf(output, "%s (@%s)\n", str_name, buff);
01383             }
01384         }
01385       else if(flag_L)
01386         {
01387           if(!flag_z)
01388             {
01389               if(context->pentry->type != REGULAR_FILE)
01390                 fprintf(output, "%p N/A  \t\t%s\n", pentry_tmp, str_name);
01391               else
01392                 {
01393                   if(context->pentry->object.file.pentry_content == NULL)
01394                     fprintf(output, "%p (not cached) \t%s\n", context->pentry, str_name);
01395                   else
01396                     fprintf(output, "%p %p \t%s\n",
01397                             context->pentry,
01398                             context->pentry->object.file.pentry_content, str_name);
01399                 }
01400             }
01401         }
01402       else                      /* only prints the name */
01403         {
01404           if(!flag_z)
01405             fprintf(output, "%s\n", str_name);
01406         }
01407 
01408       return 0;
01409     }
01410 
01411   /* If this point is reached, then the pentry is a directory */
01412 
01413   begin_cookie = 0;
01414   eod_met = UNASSIGNED_EOD;
01415 
01416   while(eod_met != END_OF_DIR)
01417     {
01418 
01419       if(flag_v)
01420         fprintf(output, "-->cache_inode_readdir(path=%s,cookie=%"PRIu64")\n",
01421                 glob_path, begin_cookie);
01422 
01423       if (cache_inode_readdir(pentry_tmp,
01424                              cachepol,
01425                              begin_cookie,
01426                              CACHE_INODE_SHELL_READDIR_SIZE,
01427                              &nbfound,
01428                              &eod_met,
01429                              dirent_array,
01430                              &context->client,
01431                              &context->context,
01432                              &context->cache_status) != CACHE_INODE_SUCCESS)
01433         {
01434           fprintf(output, "Error %d in cache_inode_readdir\n",
01435                   context->cache_status);
01436           /* after successful cache_inode_readdir, pentry_tmp may be
01437            * read locked */
01438           return context->cache_status;
01439         }
01440 
01441       for(i = 0; i < nbfound; i++)
01442         {
01443           cache_entry_t *pentry = NULL;
01444           if(!strcmp(str_name, "."))
01445             strncpy(item_path, dirent_array[i]->name.name, FSAL_MAX_PATH_LEN);
01446           else if(str_name[strlen(str_name) - 1] == '/')
01447             snprintf(item_path, FSAL_MAX_PATH_LEN, "%s%s", str_name,
01448                      dirent_array[i]->name.name);
01449           else
01450             snprintf(item_path, FSAL_MAX_PATH_LEN, "%s/%s", str_name,
01451                      dirent_array[i]->name.name);
01452 
01453           pentry = cache_inode_weakref_get(&dirent_array[i]->entry,
01454                                            &context->client,
01455                                            LRU_REQ_SCAN);
01456           if (!pentry) /* XXX Wrong, Revisit */
01457             continue;
01458 
01459           if(pentry->type == SYMBOLIC_LINK)
01460             {
01461               if(cache_inode_readlink(pentry,
01462                                       &symlink_path,
01463                                       &context->client,
01464                                       &context->context,
01465                                       &context->cache_status) != CACHE_INODE_SUCCESS)
01466                 {
01467                   log_fprintf(output, "Error executing cache_inode_readlink : %J%r\n",
01468                               ERR_CACHE_INODE, context->cache_status);
01469                   /* after successful cache_inode_readdir, pentry_tmp may be
01470                    * read locked */
01471                   return context->cache_status;
01472                 }
01473             }
01474 
01475           if(flag_l)
01476             {
01477               if(cache_inode_getattr(pentry,
01478                                      &attrs,
01479                                      &context->client,
01480                                      &context->context,
01481                                      &context->cache_status) != CACHE_INODE_SUCCESS)
01482                 {
01483                   log_fprintf(output, "Error executing cache_inode_getattr : %J%r\n",
01484                               ERR_CACHE_INODE, context->cache_status);
01485                   /* after successful cache_inode_readdir, pentry_tmp may be
01486                    * read locked */
01487                   return context->cache_status;
01488                 }
01489 
01490               print_item_line(output, &attrs, item_path, symlink_path.path);
01491             }
01492           else if(flag_S)
01493             {
01494               fprintf(output, "%s :\n", item_path);
01495               if(cache_inode_getattr(pentry,
01496                                      &attrs,
01497                                      &context->client,
01498                                      &context->context,
01499                                      &context->cache_status) != CACHE_INODE_SUCCESS)
01500                 {
01501                   log_fprintf(output, "Error executing cache_inode_getattr : %J%r\n",
01502                               ERR_CACHE_INODE, context->cache_status);
01503                   /* after successful cache_inode_readdir, pentry_tmp may be
01504                    * read locked */
01505                   return context->cache_status;
01506                 }
01507               if(!flag_z)
01508                 print_fsal_attributes(attrs, output);
01509             }
01510           else if(flag_L)
01511             {
01512               if(!flag_z)
01513                 {
01514                   if(pentry->type != REGULAR_FILE)
01515                     fprintf(output, "%p N/A \t\t%s\n",
01516                             pentry, item_path);
01517                   else
01518                     {
01519                       if(pentry->object.file.pentry_content == NULL)
01520                         fprintf(output, "%p (not cached) \t%s\n",
01521                                 pentry,
01522                                 item_path);
01523                       else
01524                         fprintf(output, "%p %p \t%s\n",
01525                                 pentry,
01526                                 pentry->object.file.pentry_content,
01527                                 item_path);
01528                     }
01529                 }
01530             }
01531           else if(flag_H)
01532             {
01533               if(!flag_z)
01534                 {
01535                   char buff[128];
01536 
01537                   pfsal_handle = &pentry->handle;
01538                   snprintmem(buff, 128, (caddr_t) pfsal_handle, sizeof(fsal_handle_t));
01539                   fprintf(output, "%s (@%s)\n", item_path, buff);
01540                 }
01541             }
01542           else
01543             {
01544               if(!flag_z)
01545                 fprintf(output, "%s\n", item_path);
01546             }
01547           cache_inode_lru_unref(pentry, &context->client, 0);
01548         }
01549 
01550       /* Ready for next iteration */
01551       LogFullDebug(COMPONENT_CACHE_INODE,
01552                    "--------------> begin_cookie = %"PRIu64", nbfound=%lu, "
01553                    "last cookie=%"PRIu64", end_cookie=%"PRIu64", "
01554                    "begin_cookie + nbfound =%"PRIu64"\n",
01555                    begin_cookie, nbfound, dirent_array[nbfound - 1]->hk.k,
01556                    end_cookie, begin_cookie + nbfound);
01557       begin_cookie = end_cookie;
01558     }
01559 
01560   /* after successful cache_inode_readdir, pentry_tmp may be
01561    * read locked */
01562 
01563   return 0;
01564 }                               /* fn_Cache_inode_ls */
01565 
01567 int fn_Cache_inode_callstat(int argc,   /* IN : number of args in argv */
01568                             char **argv,        /* IN : arg list               */
01569                             FILE * output)      /* IN : output stream          */
01570 {
01571   int i;
01572   hash_stat_t hstat;
01573 
01574   cmdCacheInode_thr_info_t *context;
01575 
01576   /* is the fs initialized ? */
01577   if(!cache_init)
01578     {
01579       fprintf(output, "Error: Cache is not initialized\n");
01580       return -1;
01581     }
01582 
01583   context = RetrieveInitializedContext();
01584 
01585   /* displaying stats */
01586   /* header: */
01587   fprintf(output,
01588           "Function             | Nb_Calls    | Success     | Retryable   | Unrecoverable\n");
01589   /* content */
01590   for(i = 0; i < CACHE_INODE_NB_COMMAND; i++)
01591     fprintf(output, "%-20s | %11u | %11u | %11u | %11u\n",
01592             cache_inode_function_names[i],
01593             context->client.stat.func_stats.nb_call[i],
01594             context->client.stat.func_stats.nb_success[i],
01595             context->client.stat.func_stats.nb_err_retryable[i],
01596             context->client.stat.func_stats.nb_err_unrecover[i]);
01597   fprintf(output,
01598           "------------------------------------------------------------------------------\n");
01599 
01600   /* Statistics for the HashTable */
01601   HashTable_GetStats(ht, &hstat);
01602   fprintf(output, "There are %zu entries in the Cache inode HashTable\n",
01603           hstat.entries);
01604   fprintf(output,
01605           "index_size=%"PRIu32"  min_rbt_num_node=%zu  max_rbt_num_node=%zu average_rbt_num_node=%zu\n",
01606           ht->parameter.index_size, hstat.min_rbt_num_node,
01607           hstat.max_rbt_num_node, hstat.average_rbt_num_node);
01608   fprintf(output,
01609           "------------------------------------------------------------------------------\n");
01610   fprintf(output,
01611           "------------------------------------------------------------------------------\n");
01612 
01613   return 0;
01614 }
01615 
01617 int fn_Cache_inode_mkdir(int argc,      /* IN : number of args in argv */
01618                          char **argv,   /* IN : arg list               */
01619                          FILE * output /* IN : output stream          */ )
01620 {
01621 
01622   char format[] = "hv";
01623 
01624   const char help_mkdir[] =
01625       "usage: mkdir [-h][-v] <path> [mode]\n"
01626       "       path: parent directory where the directory is to be created\n"
01627       "       name: name of the directory is to be created\n"
01628       "       mode: octal mode for the directory is to be created (ex: 755)\n";
01629 
01630   char glob_path[FSAL_MAX_PATH_LEN];
01631   cache_entry_t *new_hdl;
01632   cache_entry_t *subdir_hdl;
01633   fsal_status_t st;
01634   int rc, option;
01635   int flag_v = 0;
01636   int flag_h = 0;
01637   int err_flag = 0;
01638   int mode;
01639   fsal_accessmode_t fsalmode = 0755;
01640   fsal_attrib_list_t attrmkdir;
01641 
01642   char tmp_path[FSAL_MAX_PATH_LEN];
01643   char *path;
01644   char *file;
01645   char *strmode;
01646 
01647   fsal_name_t objname;
01648 
01649   cmdCacheInode_thr_info_t *context;
01650 
01651   /* is the fs initialized ? */
01652   if(!cache_init)
01653     {
01654       fprintf(output, "Error: Cache is not initialized\n");
01655       return -1;
01656     }
01657 
01658   context = RetrieveInitializedContext();
01659 
01660   /* analysing options */
01661   getopt_init();
01662   while((option = Getopt(argc, argv, format)) != -1)
01663     {
01664       switch (option)
01665         {
01666         case 'v':
01667           if(flag_v)
01668             fprintf(output,
01669                     "mkdir: warning: option 'v' has been specified more than once.\n");
01670           else
01671             flag_v++;
01672           break;
01673 
01674         case 'h':
01675           if(flag_h)
01676             fprintf(output,
01677                     "mkdir: warning: option 'h' has been specified more than once.\n");
01678           else
01679             flag_h++;
01680           break;
01681 
01682         case '?':
01683           fprintf(output, "mkdir: unknown option : %c\n", Optopt);
01684           err_flag++;
01685           break;
01686         }
01687     }
01688 
01689   if(flag_h)
01690     {
01691       fprintf(output, help_mkdir);
01692       return 0;
01693     }
01694 
01695   /* Exactly 1 or 2 args expected */
01696 
01697   if(Optind != (argc - 2) && Optind != (argc - 1))
01698     {
01699       err_flag++;
01700     }
01701   else
01702     {
01703       strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN);
01704       split_path(tmp_path, &path, &file);
01705 
01706       if(Optind == (argc - 1))
01707         {
01708           mode = 0755;
01709         }
01710       else
01711         {
01712           strmode = argv[Optind + 1];
01713           /* converting mode string to FSAL mode string */
01714           mode = atomode(strmode);
01715         }
01716 
01717       if(mode < 0)
01718         err_flag++;
01719       else
01720         {
01721           fsalmode = 0;
01722 
01723           if(mode & S_ISUID)
01724             fsalmode |= FSAL_MODE_SUID;
01725           if(mode & S_ISGID)
01726             fsalmode |= FSAL_MODE_SGID;
01727 
01728           if(mode & S_IRUSR)
01729             fsalmode |= FSAL_MODE_RUSR;
01730           if(mode & S_IWUSR)
01731             fsalmode |= FSAL_MODE_WUSR;
01732           if(mode & S_IXUSR)
01733             fsalmode |= FSAL_MODE_XUSR;
01734 
01735           if(mode & S_IRGRP)
01736             fsalmode |= FSAL_MODE_RGRP;
01737           if(mode & S_IWGRP)
01738             fsalmode |= FSAL_MODE_WGRP;
01739           if(mode & S_IXGRP)
01740             fsalmode |= FSAL_MODE_XGRP;
01741 
01742           if(mode & S_IROTH)
01743             fsalmode |= FSAL_MODE_ROTH;
01744           if(mode & S_IWOTH)
01745             fsalmode |= FSAL_MODE_WOTH;
01746           if(mode & S_IXOTH)
01747             fsalmode |= FSAL_MODE_XOTH;
01748 
01749         }
01750     }
01751 
01752   if(err_flag)
01753     {
01754       fprintf(output, help_mkdir);
01755       return -1;
01756     }
01757 
01758   /* copy current path. */
01759   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
01760 
01761   /* retrieves path handle */
01762   if((rc =
01763      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, path, context->pentry, &new_hdl,
01764                      output)))
01765     return rc;
01766 
01767   /* create fsal_name_t */
01768   st = FSAL_str2name(file, 256, &objname);
01769 
01770   if(FSAL_IS_ERROR(st))
01771     {
01772       fprintf(output, "Error executing FSAL_str2name:");
01773       print_fsal_status(output, st);
01774       fprintf(output, "\n");
01775       return st.major;
01776     }
01777 
01778   subdir_hdl = cache_inode_create(new_hdl,
01779                                   &objname,
01780                                   DIRECTORY,
01781                                   cachepol,
01782                                   fsalmode,
01783                                   NULL,
01784                                   &attrmkdir,
01785                                   &context->client,
01786                                   &context->context, &context->cache_status);
01787 
01788   if((subdir_hdl == NULL) || (context->cache_status != 0))
01789     {
01790       log_fprintf(output, "Error executing cache_inode_create(DIRECTORY) : %J%r\n",
01791                   ERR_CACHE_INODE, context->cache_status);
01792 
01793       return context->cache_status;
01794     }
01795 
01796   if(flag_v)
01797     {
01798       fprintf(output, "%s/%s successfully created (handle=%p) \n", glob_path, file,
01799               subdir_hdl);
01800     }
01801 
01802   return 0;
01803 }
01804 
01806 int fn_Cache_inode_link(int argc,       /* IN : number of args in argv */
01807                         char **argv,    /* IN : arg list               */
01808                         FILE * output /* IN : output stream          */ )
01809 {
01810 
01811   char format[] = "hv";
01812 
01813   const char help_hardlink[] =
01814       "hardlink: create a hard link.\n"
01815       "usage: hardlink [-h][-v] <target> <new_path>\n"
01816       "       target: path of an existing file.\n"
01817       "       new_path: path of the hardlink to be created\n";
01818 
01819   char glob_path_target[FSAL_MAX_PATH_LEN];
01820   char glob_path_link[FSAL_MAX_PATH_LEN];
01821 
01822   cache_entry_t *target_hdl;
01823   cache_entry_t *dir_hdl;
01824   fsal_name_t link_name;
01825 
01826   fsal_status_t st;
01827   int rc, option;
01828   int flag_v = 0;
01829   int flag_h = 0;
01830   int err_flag = 0;
01831   fsal_attrib_list_t attrlink;
01832 
01833   char tmp_path[FSAL_MAX_PATH_LEN];
01834   char *target = NULL;
01835   char *path;
01836   char *name;
01837 
01838   cmdCacheInode_thr_info_t *context;
01839 
01840   /* is the fs initialized ? */
01841   if(!cache_init)
01842     {
01843       fprintf(output, "Error: Cache is not initialized\n");
01844       return -1;
01845     }
01846 
01847   context = RetrieveInitializedContext();
01848 
01849   /* analysing options */
01850   getopt_init();
01851   while((option = Getopt(argc, argv, format)) != -1)
01852     {
01853       switch (option)
01854         {
01855         case 'v':
01856           if(flag_v)
01857             fprintf(output,
01858                     "hardlink: warning: option 'v' has been specified more than once.\n");
01859           else
01860             flag_v++;
01861           break;
01862 
01863         case 'h':
01864           if(flag_h)
01865             fprintf(output,
01866                     "hardlink: warning: option 'h' has been specified more than once.\n");
01867           else
01868             flag_h++;
01869           break;
01870 
01871         case '?':
01872           fprintf(output, "hardlink: unknown option : %c\n", Optopt);
01873           err_flag++;
01874           break;
01875         }
01876     }
01877 
01878   if(flag_h)
01879     {
01880       fprintf(output, help_hardlink);
01881       return 0;
01882     }
01883 
01884   /* There should be exactly 2 arguments */
01885   if(Optind == (argc - 2))
01886     {
01887       target = argv[Optind];
01888 
01889       strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN);
01890       split_path(tmp_path, &path, &name);
01891     }
01892   else
01893     {
01894       err_flag++;
01895     }
01896 
01897   if(err_flag)
01898     {
01899       fprintf(output, help_hardlink);
01900       return -1;
01901     }
01902 
01903   /* copy current path. */
01904   strncpy(glob_path_target, context->current_path, FSAL_MAX_PATH_LEN);
01905   strncpy(glob_path_link, context->current_path, FSAL_MAX_PATH_LEN);
01906 
01907   /* retrieves path handle */
01908   if((rc =
01909      cache_solvepath(glob_path_target, FSAL_MAX_PATH_LEN, target, context->pentry,
01910                      &target_hdl, output)))
01911     return rc;
01912 
01913   if((rc =
01914      cache_solvepath(glob_path_link, FSAL_MAX_PATH_LEN, path, context->pentry, &dir_hdl,
01915                      output)))
01916     return rc;
01917 
01918   /* create fsal_name_t */
01919   st = FSAL_str2name(name, 256, &link_name);
01920 
01921   if(FSAL_IS_ERROR(st))
01922     {
01923       fprintf(output, "Error executing FSAL_str2name:");
01924       print_fsal_status(output, st);
01925       fprintf(output, "\n");
01926       return st.major;
01927     }
01928 
01929   if(cache_inode_link(target_hdl,
01930                       dir_hdl,
01931                       &link_name,
01932                       cachepol,
01933                       &attrlink,
01934                       &context->client,
01935                       &context->context, &context->cache_status) != CACHE_INODE_SUCCESS)
01936     {
01937       log_fprintf(output, "Error executing cache_inode_link : %J%r\n",
01938                   ERR_CACHE_INODE, context->cache_status);
01939       return context->cache_status;
01940     }
01941 
01942   if(flag_v)
01943     {
01944       fprintf(output, "hardlink successfully created \n");
01945     }
01946 
01947   return 0;
01948 }
01949 
01951 int fn_Cache_inode_ln(int argc, /* IN : number of args in argv */
01952                       char **argv,      /* IN : arg list               */
01953                       FILE * output /* IN : output stream          */ )
01954 {
01955 
01956   char format[] = "hv";
01957 
01958   const char help_ln[] =
01959       "usage: ln [-h][-v] <link_content> <link_path>\n"
01960       "       link_content: content of the symbolic link to be created\n"
01961       "       link_path: path of the symbolic link to be created\n";
01962 
01963   char glob_path[FSAL_MAX_PATH_LEN];
01964   cache_entry_t *new_hdl;
01965   cache_entry_t *subdir_hdl;
01966   fsal_status_t st;
01967   int rc, option;
01968   int flag_v = 0;
01969   int flag_h = 0;
01970   int err_flag = 0;
01971   fsal_accessmode_t fsalmode = 0777;
01972   fsal_attrib_list_t attrsymlink;
01973 
01974   char tmp_path[FSAL_MAX_PATH_LEN];
01975   char *path;
01976   char *file;
01977   char *content = NULL;
01978 
01979   fsal_name_t objname;
01980 
01981   cache_inode_create_arg_t create_arg;
01982 
01983   cmdCacheInode_thr_info_t *context;
01984 
01985   memset(&create_arg, 0, sizeof(create_arg));
01986 
01987   /* is the fs initialized ? */
01988   if(!cache_init)
01989     {
01990       fprintf(output, "Error: Cache is not initialized\n");
01991       return -1;
01992     }
01993 
01994   context = RetrieveInitializedContext();
01995 
01996   /* analysing options */
01997   getopt_init();
01998   while((option = Getopt(argc, argv, format)) != -1)
01999     {
02000       switch (option)
02001         {
02002         case 'v':
02003           if(flag_v)
02004             fprintf(output,
02005                     "ln: warning: option 'v' has been specified more than once.\n");
02006           else
02007             flag_v++;
02008           break;
02009 
02010         case 'h':
02011           if(flag_h)
02012             fprintf(output,
02013                     "ln: warning: option 'h' has been specified more than once.\n");
02014           else
02015             flag_h++;
02016           break;
02017 
02018         case '?':
02019           fprintf(output, "ln: unknown option : %c\n", Optopt);
02020           err_flag++;
02021           break;
02022         }
02023     }
02024 
02025   if(flag_h)
02026     {
02027       fprintf(output, help_ln);
02028       return 0;
02029     }
02030 
02031   /* Exactly 2 args expected */
02032   if(Optind != (argc - 2))
02033     {
02034       err_flag++;
02035     }
02036   else
02037     {
02038       content = argv[Optind];
02039       strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN);
02040       split_path(tmp_path, &path, &file);
02041 
02042     }
02043 
02044   if(err_flag)
02045     {
02046       fprintf(output, help_ln);
02047       return -1;
02048     }
02049 
02050   /* copy current path. */
02051   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02052 
02053   /* retrieves path handle */
02054   if((rc =
02055      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, path, context->pentry, &new_hdl,
02056                      output)))
02057     return rc;
02058 
02059   /* create fsal_name_t */
02060   st = FSAL_str2name(file, 256, &objname);
02061 
02062   if(FSAL_IS_ERROR(st))
02063     {
02064       fprintf(output, "Error executing FSAL_str2name:");
02065       print_fsal_status(output, st);
02066       fprintf(output, "\n");
02067       return st.major;
02068     }
02069 
02070   /* create fsal_path_t */
02071   st = FSAL_str2path(content, 256, &create_arg.link_content);
02072 
02073   if(FSAL_IS_ERROR(st))
02074     {
02075       fprintf(output, "Error executing FSAL_str2path:");
02076       print_fsal_status(output, st);
02077       fprintf(output, "\n");
02078       return st.major;
02079     }
02080 
02081   if((subdir_hdl = cache_inode_create(new_hdl,
02082                                       &objname,
02083                                       SYMBOLIC_LINK,
02084                                       cachepol,
02085                                       fsalmode,
02086                                       &create_arg,
02087                                       &attrsymlink,
02088                                       &context->client,
02089                                       &context->context, &context->cache_status)) == NULL)
02090     {
02091       log_fprintf(output, "Error executing cache_inode_create(SYMBOLIC_LINK) : %J%r\n",
02092                   ERR_CACHE_INODE, context->cache_status);
02093 
02094       return context->cache_status;
02095     }
02096 
02097   if(flag_v)
02098     {
02099       fprintf(output, "%s/%s successfully created (handle=%p) \n", glob_path, file,
02100               subdir_hdl);
02101     }
02102 
02103   return 0;
02104 }
02105 
02107 int fn_Cache_inode_create(int argc,     /* IN : number of args in argv */
02108                           char **argv,  /* IN : arg list               */
02109                           FILE * output /* IN : output stream          */ )
02110 {
02111 
02112   char format[] = "hv";
02113 
02114   const char help_create[] =
02115       "usage: create [-h][-v] <path> [mode]\n"
02116       "       path: path of the file to be created\n"
02117       "       mode: octal mode for the directory to be created (ex: 644)\n";
02118 
02119   char glob_path[FSAL_MAX_PATH_LEN];
02120   cache_entry_t *new_hdl;
02121   cache_entry_t *subdir_hdl;
02122   fsal_status_t st;
02123   int rc, option;
02124   int flag_v = 0;
02125   int flag_h = 0;
02126   int err_flag = 0;
02127   int mode;
02128   fsal_accessmode_t fsalmode = 0644;
02129   fsal_attrib_list_t attrcreate;
02130 
02131   char tmp_path[FSAL_MAX_PATH_LEN];
02132   char *path;
02133   char *file;
02134   char *strmode;
02135 
02136   fsal_name_t objname;
02137 
02138   cmdCacheInode_thr_info_t *context;
02139 
02140   /* is the fs initialized ? */
02141   if(!cache_init)
02142     {
02143       fprintf(output, "Error: Cache is not initialized\n");
02144       return -1;
02145     }
02146 
02147   context = RetrieveInitializedContext();
02148 
02149   /* analysing options */
02150   getopt_init();
02151   while((option = Getopt(argc, argv, format)) != -1)
02152     {
02153       switch (option)
02154         {
02155         case 'v':
02156           if(flag_v)
02157             fprintf(output,
02158                     "create: warning: option 'v' has been specified more than once.\n");
02159           else
02160             flag_v++;
02161           break;
02162 
02163         case 'h':
02164           if(flag_h)
02165             fprintf(output,
02166                     "create: warning: option 'h' has been specified more than once.\n");
02167           else
02168             flag_h++;
02169           break;
02170 
02171         case '?':
02172           fprintf(output, "create: unknown option : %c\n", Optopt);
02173           err_flag++;
02174           break;
02175         }
02176     }
02177 
02178   if(flag_h)
02179     {
02180       fprintf(output, help_create);
02181       return 0;
02182     }
02183 
02184   /* 1 or 2 args expected */
02185   if(Optind != (argc - 2) && Optind != (argc - 1))
02186     {
02187       err_flag++;
02188     }
02189   else
02190     {
02191 
02192       strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN);
02193       split_path(tmp_path, &path, &file);
02194 
02195       if(Optind == (argc - 1))
02196         {
02197           mode = 0755;
02198         }
02199       else
02200         {
02201           strmode = argv[Optind + 1];
02202           /* converting mode string to FSAL mode string */
02203           mode = atomode(strmode);
02204         }
02205 
02206       if(mode < 0)
02207         err_flag++;
02208       else
02209         {
02210 
02211           fsalmode = 0;
02212 
02213           if(mode & S_ISUID)
02214             fsalmode |= FSAL_MODE_SUID;
02215           if(mode & S_ISGID)
02216             fsalmode |= FSAL_MODE_SGID;
02217 
02218           if(mode & S_IRUSR)
02219             fsalmode |= FSAL_MODE_RUSR;
02220           if(mode & S_IWUSR)
02221             fsalmode |= FSAL_MODE_WUSR;
02222           if(mode & S_IXUSR)
02223             fsalmode |= FSAL_MODE_XUSR;
02224 
02225           if(mode & S_IRGRP)
02226             fsalmode |= FSAL_MODE_RGRP;
02227           if(mode & S_IWGRP)
02228             fsalmode |= FSAL_MODE_WGRP;
02229           if(mode & S_IXGRP)
02230             fsalmode |= FSAL_MODE_XGRP;
02231 
02232           if(mode & S_IROTH)
02233             fsalmode |= FSAL_MODE_ROTH;
02234           if(mode & S_IWOTH)
02235             fsalmode |= FSAL_MODE_WOTH;
02236           if(mode & S_IXOTH)
02237             fsalmode |= FSAL_MODE_XOTH;
02238 
02239         }
02240 
02241     }
02242 
02243   if(err_flag)
02244     {
02245       fprintf(output, help_create);
02246       return -1;
02247     }
02248 
02249   /* copy current path. */
02250   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02251 
02252   /* retrieves path handle */
02253   if((rc =
02254      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, path, context->pentry, &new_hdl,
02255                      output)))
02256     return rc;
02257 
02258   /* create fsal_name_t */
02259   st = FSAL_str2name(file, 256, &objname);
02260 
02261   if(FSAL_IS_ERROR(st))
02262     {
02263       fprintf(output, "Error executing FSAL_str2name:");
02264       print_fsal_status(output, st);
02265       fprintf(output, "\n");
02266       return st.major;
02267     }
02268 
02269   if((subdir_hdl = cache_inode_create(new_hdl,
02270                                       &objname,
02271                                       REGULAR_FILE,
02272                                       cachepol,
02273                                       fsalmode,
02274                                       NULL,
02275                                       &attrcreate,
02276                                       &context->client,
02277                                       &context->context, &context->cache_status)) == NULL)
02278     {
02279       log_fprintf(output, "Error executing cache_inode_create(DIRECTORY) : %J%r\n",
02280                   ERR_CACHE_INODE, context->cache_status);
02281 
02282       return context->cache_status;
02283     }
02284 
02285   if(flag_v)
02286     {
02287       fprintf(output, "%s/%s successfully created (handle=%p) \n", glob_path, file,
02288               subdir_hdl);
02289     }
02290 
02291   return 0;
02292 }
02293 
02295 int fn_Cache_inode_rename(int argc,     /* IN : number of args in argv */
02296                           char **argv,  /* IN : arg list               */
02297                           FILE * output /* IN : output stream          */ )
02298 {
02299   char format[] = "hv";
02300 
02301   const char help_rename[] = "usage: rename [-h][-v] <src> <dest>\n";
02302 
02303   char src_glob_path[FSAL_MAX_PATH_LEN];
02304   char tgt_glob_path[FSAL_MAX_PATH_LEN];
02305 
02306   cache_entry_t *src_path_pentry;
02307   cache_entry_t *tgt_path_pentry;
02308   fsal_name_t src_name;
02309   fsal_name_t tgt_name;
02310 
02311   fsal_status_t st;
02312   int rc, option;
02313   int flag_v = 0;
02314   int flag_h = 0;
02315   int err_flag = 0;
02316 
02317   char tmp_path1[FSAL_MAX_PATH_LEN];
02318   char tmp_path2[FSAL_MAX_PATH_LEN];
02319   char *src_path;
02320   char *src_file;
02321   char *tgt_path;
02322   char *tgt_file;
02323 
02324   fsal_attrib_list_t attrsrc;
02325   fsal_attrib_list_t attrdest;
02326 
02327   cmdCacheInode_thr_info_t *context;
02328 
02329   /* is the fs initialized ? */
02330   if(!cache_init)
02331     {
02332       fprintf(output, "Error: Cache is not initialized\n");
02333       return -1;
02334     }
02335 
02336   context = RetrieveInitializedContext();
02337 
02338   /* analysing options */
02339   getopt_init();
02340   while((option = Getopt(argc, argv, format)) != -1)
02341     {
02342       switch (option)
02343         {
02344         case 'v':
02345           if(flag_v)
02346             fprintf(output,
02347                     "rename: warning: option 'v' has been specified more than once.\n");
02348           else
02349             flag_v++;
02350           break;
02351 
02352         case 'h':
02353           if(flag_h)
02354             fprintf(output,
02355                     "rename: warning: option 'h' has been specified more than once.\n");
02356           else
02357             flag_h++;
02358           break;
02359 
02360         case '?':
02361           fprintf(output, "rename: unknown option : %c\n", Optopt);
02362           err_flag++;
02363           break;
02364         }
02365     }
02366 
02367   if(flag_h)
02368     {
02369       fprintf(output, help_rename);
02370       return 0;
02371     }
02372 
02373   /* Exactly 2 args expected */
02374   if(Optind != (argc - 2))
02375     {
02376       err_flag++;
02377     }
02378   else
02379     {
02380       strncpy(tmp_path1, argv[Optind], FSAL_MAX_PATH_LEN);
02381       split_path(tmp_path1, &src_path, &src_file);
02382 
02383       strncpy(tmp_path2, argv[Optind + 1], FSAL_MAX_PATH_LEN);
02384       split_path(tmp_path2, &tgt_path, &tgt_file);
02385     }
02386 
02387   if(err_flag)
02388     {
02389       fprintf(output, help_rename);
02390       return -1;
02391     }
02392 
02393   if(flag_v)
02394     fprintf(output, "Renaming %s (dir %s) to %s (dir %s)\n", src_file, src_path, tgt_file,
02395             tgt_path);
02396 
02397   /* copy current path. */
02398   strncpy(src_glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02399   strncpy(tgt_glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02400 
02401   /* retrieves paths handles */
02402   if((rc = cache_solvepath(src_glob_path,
02403                           FSAL_MAX_PATH_LEN,
02404                            src_path, context->pentry, &src_path_pentry, output)))
02405     return rc;
02406 
02407   if((rc = cache_solvepath(tgt_glob_path,
02408                           FSAL_MAX_PATH_LEN,
02409                           tgt_path, context->pentry, &tgt_path_pentry, output)))
02410     return rc;
02411 
02412   /* create fsal_name_t */
02413 
02414   st = FSAL_str2name(src_file, 256, &src_name);
02415 
02416   if(FSAL_IS_ERROR(st))
02417     {
02418       fprintf(output, "Error executing FSAL_str2name:");
02419       print_fsal_status(output, st);
02420       fprintf(output, "\n");
02421       return st.major;
02422     }
02423 
02424   st = FSAL_str2name(tgt_file, 256, &tgt_name);
02425 
02426   if(FSAL_IS_ERROR(st))
02427     {
02428       fprintf(output, "Error executing FSAL_str2name:");
02429       print_fsal_status(output, st);
02430       fprintf(output, "\n");
02431       return st.major;
02432     }
02433 
02434   /* Rename operation */
02435   if(cache_inode_rename(src_path_pentry,
02436                         &src_name,
02437                         tgt_path_pentry,
02438                         &tgt_name,
02439                         &attrsrc,
02440                         &attrdest,
02441                         &context->client,
02442                         &context->context, &context->cache_status) != CACHE_INODE_SUCCESS)
02443     {
02444       log_fprintf(output, "Error executing cache_inode_rename : %J%r\n",
02445                   ERR_CACHE_INODE, context->cache_status);
02446 
02447       return context->cache_status;
02448     }
02449 
02450   if(flag_v)
02451     fprintf(output, "%s/%s successfully renamed to %s/%s\n",
02452             src_glob_path, src_file, tgt_glob_path, tgt_file);
02453 
02454   return 0;
02455 }
02456 
02458 int fn_Cache_inode_unlink(int argc,     /* IN : number of args in argv */
02459                           char **argv,  /* IN : arg list               */
02460                           FILE * output /* IN : output stream          */ )
02461 {
02462 
02463   char format[] = "hv";
02464 
02465   const char help_ln[] = "usage: ln [-h][-v] <path>\n";
02466 
02467   char glob_path[FSAL_MAX_PATH_LEN];
02468   cache_entry_t *new_hdl;
02469   fsal_status_t st;
02470   int rc, option;
02471   int flag_v = 0;
02472   int flag_h = 0;
02473   int err_flag = 0;
02474 
02475   char tmp_path[FSAL_MAX_PATH_LEN];
02476   char *path;
02477   char *file;
02478 
02479   fsal_name_t objname;
02480   fsal_attrib_list_t attrparent;
02481 
02482   cmdCacheInode_thr_info_t *context;
02483 
02484   /* is the fs initialized ? */
02485   if(!cache_init)
02486     {
02487       fprintf(output, "Error: Cache is not initialized\n");
02488       return -1;
02489     }
02490 
02491   context = RetrieveInitializedContext();
02492 
02493   /* analysing options */
02494   getopt_init();
02495   while((option = Getopt(argc, argv, format)) != -1)
02496     {
02497       switch (option)
02498         {
02499         case 'v':
02500           if(flag_v)
02501             fprintf(output,
02502                     "unlink: warning: option 'v' has been specified more than once.\n");
02503           else
02504             flag_v++;
02505           break;
02506 
02507         case 'h':
02508           if(flag_h)
02509             fprintf(output,
02510                     "unlink: warning: option 'h' has been specified more than once.\n");
02511           else
02512             flag_h++;
02513           break;
02514 
02515         case '?':
02516           fprintf(output, "unlink: unknown option : %c\n", Optopt);
02517           err_flag++;
02518           break;
02519         }
02520     }
02521 
02522   if(flag_h)
02523     {
02524       fprintf(output, help_ln);
02525       return 0;
02526     }
02527 
02528   /* Exactly 2 args expected */
02529   if(Optind != (argc - 1))
02530     {
02531       err_flag++;
02532     }
02533   else
02534     {
02535       strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN);
02536       split_path(tmp_path, &path, &file);
02537 
02538     }
02539 
02540   if(err_flag)
02541     {
02542       fprintf(output, help_ln);
02543       return -1;
02544     }
02545 
02546   /* copy current path. */
02547   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02548 
02549   /* retrieves path handle */
02550   if((rc =
02551      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, path, context->pentry, &new_hdl,
02552                      output)))
02553     return rc;
02554 
02555   /* create fsal_name_t */
02556   st = FSAL_str2name(file, 256, &objname);
02557 
02558   if(FSAL_IS_ERROR(st))
02559     {
02560       fprintf(output, "Error executing FSAL_str2name:");
02561       print_fsal_status(output, st);
02562       fprintf(output, "\n");
02563       return st.major;
02564     }
02565 
02566   if(FSAL_IS_ERROR(st))
02567     {
02568       fprintf(output, "Error executing FSAL_str2path:");
02569       print_fsal_status(output, st);
02570       fprintf(output, "\n");
02571       return st.major;
02572     }
02573 
02574   cache_inode_remove(new_hdl,
02575                      &objname,
02576                      &attrparent,
02577                      &context->client, &context->context, &context->cache_status);
02578   if(context->cache_status != CACHE_INODE_SUCCESS)
02579     {
02580       log_fprintf(output, "Error executing cache_inode_remove : %J%r\n",
02581                   ERR_CACHE_INODE, context->cache_status);
02582       return context->cache_status;
02583     }
02584 
02585   if(flag_v)
02586     {
02587       fprintf(output, "%s/%s successfully unlinked\n", glob_path, file);
02588     }
02589 
02590   return 0;
02591 }
02592 
02599 int fn_Cache_inode_setattr(int argc,    /* IN : number of args in argv */
02600                            char **argv, /* IN : arg list               */
02601                            FILE * output /* IN : output stream          */ )
02602 {
02603 
02604   char format[] = "hv";
02605 
02606   const char help_setattr[] =
02607       "usage: setattr [-h][-v] <path> <attr>=<value>,<attr>=<value>,...\n";
02608 
02609   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
02610 
02611   cache_entry_t *obj_hdl;       /* handle of the object    */
02612   fsal_attrib_list_t set_attrs; /* attributes to be setted */
02613   cache_inode_status_t cache_status;    /* FSAL return status      */
02614 
02615   int rc, option;
02616   int flag_v = 0;
02617   int flag_h = 0;
02618   int err_flag = 0;
02619 
02620   char file[FSAL_MAX_NAME_LEN]; /* the relative path to the object */
02621   char *attr_list = NULL;       /* attribute name */
02622 
02623   cmdCacheInode_thr_info_t *context;
02624 
02625   /* is the fs initialized ? */
02626   if(!cache_init)
02627     {
02628       fprintf(output, "Error: Cache is not initialized\n");
02629       return -1;
02630     }
02631 
02632   context = RetrieveInitializedContext();
02633 
02634   /* analysing options */
02635   getopt_init();
02636 
02637   while((option = Getopt(argc, argv, format)) != -1)
02638     {
02639       switch (option)
02640         {
02641         case 'v':
02642           if(flag_v)
02643             fprintf(output,
02644                     "setattr: warning: option 'v' has been specified more than once.\n");
02645           else
02646             flag_v++;
02647           break;
02648 
02649         case 'h':
02650           if(flag_h)
02651             fprintf(output,
02652                     "setattr: warning: option 'h' has been specified more than once.\n");
02653           else
02654             flag_h++;
02655           break;
02656 
02657         case '?':
02658           fprintf(output, "setattr: unknown option : %c\n", Optopt);
02659           err_flag++;
02660           break;
02661         }
02662     }
02663 
02664   if(flag_h)
02665     {
02666 
02667       shell_attribute_t *curr_attr;
02668 
02669       /* print usage */
02670       fprintf(output, help_setattr);
02671 
02672       fprintf(output, "\n<attr> can be one of the following values:\n");
02673 
02674       /* print attribute list */
02675 
02676       for(curr_attr = shell_attr_list; curr_attr->attr_type != ATTR_NONE; curr_attr++)
02677         {
02678           switch (curr_attr->attr_type)
02679             {
02680             case ATTR_32:
02681               fprintf(output, "\t %s \t:\t 32 bits integer\n", curr_attr->attr_name);
02682               break;
02683 
02684             case ATTR_64:
02685               fprintf(output, "\t %s \t:\t 64 bits integer\n", curr_attr->attr_name);
02686               break;
02687 
02688             case ATTR_OCTAL:
02689               fprintf(output, "\t %s \t:\t octal\n", curr_attr->attr_name);
02690               break;
02691 
02692             case ATTR_TIME:
02693               fprintf(output, "\t %s \t:\t time (format: YYYYMMDDhhmmss)\n",
02694                       curr_attr->attr_name);
02695               break;
02696             default:
02697               break;
02698             }
02699         }
02700 
02701       return 0;
02702     }
02703 
02704   /* Exactly 2 args expected (path and attributes list) */
02705 
02706   if(Optind != (argc - 2))
02707     {
02708       err_flag++;
02709     }
02710   else
02711     {
02712       strcpy(file, argv[Optind]);
02713       attr_list = argv[Optind + 1];
02714     }
02715 
02716   if(err_flag)
02717     {
02718       fprintf(output, help_setattr);
02719       return -1;
02720     }
02721 
02722   /* copy current absolute path to a local variable. */
02723   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02724 
02725   /* retrieve handle to the file whose attributes are to be changed */
02726   if((rc =
02727      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
02728                      output)))
02729     return rc;
02730 
02731   /* Convert the peer (attr_name,attr_val) to an FSAL attribute structure. */
02732   rc = MkFSALSetAttrStruct(attr_list, &set_attrs);
02733 
02734   /* interprets output code */
02735   switch (rc)
02736     {
02737     case 0:
02738       /* OK */
02739       break;
02740 
02741     case EFAULT:
02742       fprintf(output, "setattr: Internal error.\n");
02743       return rc;
02744 
02745     case ENOENT:
02746       fprintf(output, "setattr: Unknown attribute in list %s\n", attr_list);
02747       return rc;
02748 
02749     case EINVAL:
02750       fprintf(output, "setattr: Invalid value for attribute in list %s\n", attr_list);
02751       return rc;
02752 
02753     default:
02754       fprintf(output, "setattr: Error %d converting attributes.\n", rc);
02755       return rc;
02756     }
02757 
02758   /* if verbose mode is on, we print the attributes to be set */
02759   if(flag_v)
02760     {
02761       print_fsal_attributes(set_attrs, output);
02762     }
02763 
02764   /* executes set attrs */
02765   if((cache_status = cache_inode_setattr(obj_hdl,
02766                                          &set_attrs,
02767                                          &context->client,
02768                                          &context->context,
02769                                          &context->cache_status)) != CACHE_INODE_SUCCESS)
02770 
02771     {
02772       log_fprintf(output, "Error executing cache_inode_setattr : %J%r\n",
02773                   ERR_CACHE_INODE, context->cache_status);
02774       return context->cache_status;
02775     }
02776 
02777   return 0;
02778 }
02779 
02786 int fn_Cache_inode_access(int argc,     /* IN : number of args in argv */
02787                           char **argv,  /* IN : arg list               */
02788                           FILE * output /* IN : output stream          */ )
02789 {
02790 
02791   char format[] = "hv";
02792 
02793   const char help_access[] =
02794       "usage: access [-h][-v] <rights> <path>\n"
02795       "\n"
02796       "   -h : print this help\n"
02797       "   -v : verbose mode\n"
02798       "   -A : test access from attributes\n"
02799       "        ( call to getattr + test_access instead of access )\n"
02800       "\n"
02801       " <rights> : a set of the following characters:\n"
02802       "    F: test file existence\n"
02803       "    R: test read permission\n"
02804       "    W: test write permission\n"
02805       "    X: test execute permission\n"
02806       "\n"
02807       "Example: access -A RX my_dir\n"
02808       "test read and exec rights for directory \"my_dir\"\n"
02809       "by doing a getattr and a test_access call.\n\n";
02810 
02811   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
02812   cache_entry_t *obj_hdl;       /* handle of the object        */
02813   fsal_accessflags_t test_perms;        /* permissions to be tested    */
02814 
02815   int rc, option;
02816   unsigned int i;
02817   int flag_v = 0;
02818   int flag_h = 0;
02819   int err_flag = 0;
02820 
02821   char *file = NULL;            /* the relative path to the object */
02822   char *str_perms = NULL;       /* string that represents the permissions to be tested */
02823 
02824   cmdCacheInode_thr_info_t *context;
02825 
02826   /* is the fs initialized ? */
02827   if(!cache_init)
02828     {
02829       fprintf(output, "Error: Cache is not initialized\n");
02830       return -1;
02831     }
02832 
02833   context = RetrieveInitializedContext();
02834 
02835   /* analysing options */
02836 
02837   getopt_init();
02838   while((option = Getopt(argc, argv, format)) != -1)
02839     {
02840       switch (option)
02841         {
02842         case 'v':
02843           if(flag_v)
02844             fprintf(output,
02845                     "access: warning: option 'v' has been specified more than once.\n");
02846           else
02847             flag_v++;
02848           break;
02849 
02850         case 'h':
02851           if(flag_h)
02852             fprintf(output,
02853                     "access: warning: option 'h' has been specified more than once.\n");
02854           else
02855             flag_h++;
02856           break;
02857 
02858         default:
02859         case '?':
02860           fprintf(output, "access: unknown option : %c\n", Optopt);
02861           err_flag++;
02862           break;
02863         }
02864     }
02865 
02866   if(flag_h)
02867     {
02868       /* print usage */
02869       fprintf(output, help_access);
02870       return 0;
02871     }
02872 
02873   /* Exactly 2 args expected */
02874   if(Optind != (argc - 2))
02875     {
02876       err_flag++;
02877     }
02878   else
02879     {
02880       str_perms = argv[Optind];
02881       file = argv[Optind + 1];
02882     }
02883 
02884   if(err_flag)
02885     {
02886       fprintf(output, help_access);
02887       return -1;
02888     }
02889 
02890   /* copy current absolute path to a local variable. */
02891   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
02892 
02893   /* retrieve handle to the file whose permissions are to be tested */
02894   if((rc =
02895      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
02896                      output)))
02897     return rc;
02898 
02899   /* Convert the permission string to an fsal access test. */
02900   test_perms = 0;
02901 
02902   for(i = 0; i < strlen(str_perms); i++)
02903     {
02904       switch (str_perms[i])
02905         {
02906         case 'F':
02907           if(flag_v)
02908             fprintf(output, "F_OK flag\n");
02909           test_perms |= FSAL_F_OK;
02910           break;
02911 
02912         case 'R':
02913           if(flag_v)
02914             fprintf(output, "R_OK flag\n");
02915           test_perms |= FSAL_R_OK;
02916           break;
02917 
02918         case 'W':
02919           if(flag_v)
02920             fprintf(output, "W_OK flag\n");
02921           test_perms |= FSAL_W_OK;
02922           break;
02923 
02924         case 'X':
02925           if(flag_v)
02926             fprintf(output, "X_OK flag\n");
02927           test_perms |= FSAL_X_OK;
02928           break;
02929 
02930         default:
02931           fprintf(output, "**** Invalid test: %c ****\n", str_perms[i]);
02932           fprintf(output, help_access);
02933           return -1;
02934         }
02935     }
02936 
02937   /* Call to FSAL */
02938 
02939   if((context->cache_status = cache_inode_access(obj_hdl,
02940                                                  test_perms,
02941                                                  &context->client,
02942                                                  &context->context,
02943                                                  &context->cache_status)) !=
02944      CACHE_INODE_SUCCESS)
02945     {
02946       log_fprintf(output, "Error executing cache_inode_access : %J%r\n",
02947                   ERR_CACHE_INODE, context->cache_status);
02948       return context->cache_status;
02949     }
02950   else
02951     {
02952       fprintf(output, "access: Access granted.\n");
02953       return 0;
02954     }
02955 }
02956 
02958 int fn_Cache_inode_data_cache(int argc, /* IN : number of args in argv */
02959                               char **argv,      /* IN : arg list               */
02960                               FILE * output /* IN : output stream          */ )
02961 {
02962   char format[] = "hv";
02963 
02964   const char help_data_cache[] =
02965       "usage: data_cache [-h][-v]  <path>\n"
02966       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
02967 
02968   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
02969   cache_entry_t *obj_hdl;       /* handle of the object        */
02970 
02971   int rc, option;
02972   int flag_v = 0;
02973   int flag_h = 0;
02974   int err_flag = 0;
02975 
02976   char *file = NULL;            /* the relative path to the object */
02977 
02978 #ifdef _USE_PROXY
02979   fsal_name_t name;
02980 #endif
02981 
02982   cmdCacheInode_thr_info_t *context;
02983 
02984   /* is the fs initialized ? */
02985   if(!cache_init)
02986     {
02987       fprintf(output, "Error: Cache is not initialized\n");
02988       return -1;
02989     }
02990 
02991   context = RetrieveInitializedContext();
02992 
02993   /* analysing options */
02994 
02995   getopt_init();
02996   while((option = Getopt(argc, argv, format)) != -1)
02997     {
02998       switch (option)
02999         {
03000         case 'v':
03001           if(flag_v)
03002             fprintf(output,
03003                     "access: warning: option 'v' has been specified more than once.\n");
03004           else
03005             flag_v++;
03006           break;
03007 
03008         case 'h':
03009           if(flag_h)
03010             fprintf(output,
03011                     "access: warning: option 'h' has been specified more than once.\n");
03012           else
03013             flag_h++;
03014           break;
03015 
03016         default:
03017         case '?':
03018           fprintf(output, "access: unknown option : %c\n", Optopt);
03019           err_flag++;
03020           break;
03021         }
03022     }
03023 
03024   if(flag_h)
03025     {
03026       /* print usage */
03027       fprintf(output, help_data_cache);
03028       return 0;
03029     }
03030 
03031   /* Exactly 1 args expected */
03032   if(Optind != (argc - 1))
03033     {
03034       err_flag++;
03035     }
03036   else
03037     {
03038       file = argv[Optind];
03039     }
03040 
03041   if(err_flag)
03042     {
03043       fprintf(output, help_data_cache);
03044       return -1;
03045     }
03046 
03047   /* copy current absolute path to a local variable. */
03048   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
03049 
03050   /* retrieve handle to the file whose permissions are to be tested */
03051   if((rc =
03052      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
03053                      output)))
03054     return rc;
03055 
03056 #ifdef _USE_PROXY
03057   if(FSAL_IS_ERROR(FSAL_str2name(file, MAXPATHLEN, &name)))
03058     {
03059       context->cache_status = CACHE_INODE_FSAL_ERROR;
03060       log_fprintf(output, "Error opening file during cache_inode_add_cache : %J%r\n",
03061                   ERR_CACHE_INODE, context->cache_status);
03062       return context->cache_status;
03063 
03064     }
03065 
03066   if(cache_inode_open_by_name(context->pentry,
03067                               &name,
03068                               obj_hdl,
03069                               &context->client,
03070                               FSAL_O_RDWR,
03071                               &context->context,
03072                               &context->cache_status) != CACHE_INODE_SUCCESS)
03073     {
03074       log_fprintf(output, "Error opening file during cache_inode_add_cache : %J%r\n",
03075                   ERR_CACHE_INODE, context->cache_status);
03076       return context->cache_status;
03077     }
03078 #endif
03079 
03080   if(flag_v)
03081     printf("---> data_cache using pentry_inode = %p\n", obj_hdl);
03082 
03083   if(cache_inode_add_data_cache(obj_hdl, &context->client, &context->context,
03084                                 &context->cache_status) != CACHE_INODE_SUCCESS)
03085     {
03086       log_fprintf(output, "Error executing cache_inode_add_cache : %J%r\n",
03087                   ERR_CACHE_INODE, context->cache_status);
03088       return context->cache_status;
03089     }
03090 
03091   if(flag_v)
03092     {
03093       fprintf(output, "Entry %p is now boud to datacache entry %p\n", obj_hdl,
03094               obj_hdl->object.file.pentry_content);
03095     }
03096 
03097   return 0;
03098 }                               /* fn_Cache_inode_data_cache */
03099 
03101 int fn_Cache_inode_release_cache(int argc,      /* IN : number of args in argv */
03102                                  char **argv,   /* IN : arg list               */
03103                                  FILE * output /* IN : output stream          */ )
03104 {
03105   char format[] = "hv";
03106 
03107   const char help_release_cache[] =
03108       "usage: release_cache [-h][-v]  <path>\n"
03109       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
03110 
03111   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
03112   cache_entry_t *obj_hdl;       /* handle of the object        */
03113 
03114   int rc, option;
03115   int flag_v = 0;
03116   int flag_h = 0;
03117   int err_flag = 0;
03118 
03119   char *file = NULL;            /* the relative path to the object */
03120 
03121   cmdCacheInode_thr_info_t *context;
03122 
03123   /* is the fs initialized ? */
03124   if(!cache_init)
03125     {
03126       fprintf(output, "Error: Cache is not initialized\n");
03127       return -1;
03128     }
03129 
03130   context = RetrieveInitializedContext();
03131 
03132   /* analysing options */
03133 
03134   getopt_init();
03135   while((option = Getopt(argc, argv, format)) != -1)
03136     {
03137       switch (option)
03138         {
03139         case 'v':
03140           if(flag_v)
03141             fprintf(output,
03142                     "access: warning: option 'v' has been specified more than once.\n");
03143           else
03144             flag_v++;
03145           break;
03146 
03147         case 'h':
03148           if(flag_h)
03149             fprintf(output,
03150                     "access: warning: option 'h' has been specified more than once.\n");
03151           else
03152             flag_h++;
03153           break;
03154 
03155         default:
03156         case '?':
03157           fprintf(output, "access: unknown option : %c\n", Optopt);
03158           err_flag++;
03159           break;
03160         }
03161     }
03162 
03163   if(flag_h)
03164     {
03165       /* print usage */
03166       fprintf(output, help_release_cache);
03167       return 0;
03168     }
03169 
03170   /* Exactly 1 args expected */
03171   if(Optind != (argc - 1))
03172     {
03173       err_flag++;
03174     }
03175   else
03176     {
03177       file = argv[Optind];
03178     }
03179 
03180   if(err_flag)
03181     {
03182       fprintf(output, help_release_cache);
03183       return -1;
03184     }
03185 
03186   /* copy current absolute path to a local variable. */
03187   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
03188 
03189   /* retrieve handle to the file whose permissions are to be tested */
03190   if((rc =
03191      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
03192                      output)))
03193     return rc;
03194 
03195   if(cache_inode_release_data_cache
03196      (obj_hdl, &context->client, &context->context,
03197       &context->cache_status) != CACHE_INODE_SUCCESS)
03198     {
03199       log_fprintf(output, "Error executing cache_inode_release_cache : %J%r\n",
03200                   ERR_CACHE_INODE, context->cache_status);
03201       return context->cache_status;
03202     }
03203 
03204   if(flag_v)
03205     {
03206       fprintf(output, "Entry %p is no more bounded to datacache\n", obj_hdl);
03207     }
03208 
03209   return 0;
03210 }                               /* fn_Cache_inode_release_cache */
03211 
03213 int fn_Cache_inode_recover_cache(int argc,      /* IN : number of args in argv */
03214                                  char **argv,   /* IN : arg list               */
03215                                  FILE * output /* IN : output stream          */ )
03216 {
03217   char format[] = "hv";
03218 
03219   const char help_recover_cache[] =
03220       "usage: recover_cache [-h][-v]  <path>\n"
03221       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
03222 
03223   cache_content_status_t cache_content_status;
03224 
03225   int option;
03226   int flag_v = 0;
03227   int flag_h = 0;
03228   int err_flag = 0;
03229 
03230   cmdCacheInode_thr_info_t *context;
03231 
03232   /* is the fs initialized ? */
03233   if(!cache_init)
03234     {
03235       fprintf(output, "Error: Cache is not initialized\n");
03236       return -1;
03237     }
03238 
03239   context = RetrieveInitializedContext();
03240 
03241   /* analysing options */
03242 
03243   getopt_init();
03244   while((option = Getopt(argc, argv, format)) != -1)
03245     {
03246       switch (option)
03247         {
03248         case 'v':
03249           if(flag_v)
03250             fprintf(output,
03251                     "access: warning: option 'v' has been specified more than once.\n");
03252           else
03253             flag_v++;
03254           break;
03255 
03256         case 'h':
03257           if(flag_h)
03258             fprintf(output,
03259                     "access: warning: option 'h' has been specified more than once.\n");
03260           else
03261             flag_h++;
03262           break;
03263 
03264         default:
03265         case '?':
03266           fprintf(output, "access: unknown option : %c\n", Optopt);
03267           err_flag++;
03268           break;
03269         }
03270     }
03271 
03272   if(flag_h)
03273     {
03274       /* print usage */
03275       fprintf(output, help_recover_cache);
03276       return 0;
03277     }
03278 
03279   /* Exactly 1 args expected */
03280   if(Optind != argc)
03281     {
03282       err_flag++;
03283     }
03284 
03285   if(err_flag)
03286     {
03287       fprintf(output, help_recover_cache);
03288       return -1;
03289     }
03290 
03291   if(cache_content_crash_recover(EXPORT_ID,
03292                                  0,
03293                                  1,
03294                                  (cache_content_client_t *) context->client.
03295                                  pcontent_client, &context->client, &context->context,
03296                                  &cache_content_status) != CACHE_CONTENT_SUCCESS)
03297     {
03298       fprintf(output, "Error executing cache_content_crash_recover: %d\n",
03299               cache_content_status);
03300       return cache_content_status;
03301     }
03302 
03303   if(flag_v)
03304     {
03305       fprintf(output, "Data cache has been recovered\n");
03306     }
03307 
03308   return 0;
03309 }                               /* fn_Cache_inode_recover_cache */
03310 
03312 int fn_Cache_inode_refresh_cache(int argc,      /* IN : number of args in argv */
03313                                  char **argv,   /* IN : arg list               */
03314                                  FILE * output /* IN : output stream          */ )
03315 {
03316   char format[] = "hv";
03317 
03318   const char help_refresh_cache[] =
03319       "usage: refresh_cache [-h][-v]  <path>\n"
03320       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
03321 
03322   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
03323   cache_entry_t *obj_hdl;       /* handle of the object        */
03324   cache_content_status_t cache_content_status;
03325 
03326   int rc, option;
03327   int flag_v = 0;
03328   int flag_h = 0;
03329   int err_flag = 0;
03330 
03331   char *file = NULL;            /* the relative path to the object */
03332 
03333   cmdCacheInode_thr_info_t *context;
03334 
03335   /* is the fs initialized ? */
03336   if(!cache_init)
03337     {
03338       fprintf(output, "Error: Cache is not initialized\n");
03339       return -1;
03340     }
03341 
03342   context = RetrieveInitializedContext();
03343 
03344   /* analysing options */
03345 
03346   getopt_init();
03347   while((option = Getopt(argc, argv, format)) != -1)
03348     {
03349       switch (option)
03350         {
03351         case 'v':
03352           if(flag_v)
03353             fprintf(output,
03354                     "access: warning: option 'v' has been specified more than once.\n");
03355           else
03356             flag_v++;
03357           break;
03358 
03359         case 'h':
03360           if(flag_h)
03361             fprintf(output,
03362                     "access: warning: option 'h' has been specified more than once.\n");
03363           else
03364             flag_h++;
03365           break;
03366 
03367         default:
03368         case '?':
03369           fprintf(output, "access: unknown option : %c\n", Optopt);
03370           err_flag++;
03371           break;
03372         }
03373     }
03374 
03375   if(flag_h)
03376     {
03377       /* print usage */
03378       fprintf(output, help_refresh_cache);
03379       return 0;
03380     }
03381 
03382   /* Exactly 1 args expected */
03383   if(Optind != (argc - 1))
03384     {
03385       err_flag++;
03386     }
03387   else
03388     {
03389       file = argv[Optind];
03390     }
03391 
03392   if(err_flag)
03393     {
03394       fprintf(output, help_refresh_cache);
03395       return -1;
03396     }
03397 
03398   /* copy current absolute path to a local variable. */
03399   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
03400 
03401   /* retrieve handle to the file whose permissions are to be tested */
03402   if((rc =
03403      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
03404                      output)))
03405     return rc;
03406 
03407   if(obj_hdl->object.file.pentry_content == NULL)
03408     {
03409       fprintf(output, "Error: this entry is not data cached\n");
03410       return 1;
03411     }
03412 
03413   if(cache_content_refresh(obj_hdl->object.file.pentry_content,
03414                            (cache_content_client_t *) context->client.pcontent_client,
03415                            &context->context,
03416                            FORCE_FROM_FSAL,
03417                            &cache_content_status) != CACHE_CONTENT_SUCCESS)
03418     {
03419       fprintf(output, "Error executing cache_content_refresh: %d\n",
03420               cache_content_status);
03421       return cache_content_status;
03422     }
03423 
03424   if(flag_v)
03425     {
03426       fprintf(output, "Entry %p has been refreshed\n", obj_hdl);
03427     }
03428 
03429   return 0;
03430 }                               /* fn_Cache_inode_refresh_cache */
03431 
03433 int fn_Cache_inode_flush_cache(int argc,        /* IN : number of args in argv */
03434                                char **argv,     /* IN : arg list               */
03435                                FILE * output /* IN : output stream          */ )
03436 {
03437   char format[] = "hv";
03438 
03439   const char help_flush_cache[] =
03440       "usage: flush_cache [-h][-v]  <path>\n"
03441       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
03442 
03443   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
03444   cache_entry_t *obj_hdl;       /* handle of the object        */
03445   cache_content_status_t cache_content_status;
03446 
03447   int rc, option;
03448   int flag_v = 0;
03449   int flag_h = 0;
03450   int err_flag = 0;
03451 
03452   char *file = NULL;            /* the relative path to the object */
03453 
03454   cmdCacheInode_thr_info_t *context;
03455 
03456   /* is the fs initialized ? */
03457   if(!cache_init)
03458     {
03459       fprintf(output, "Error: Cache is not initialized\n");
03460       return -1;
03461     }
03462 
03463   context = RetrieveInitializedContext();
03464 
03465   /* analysing options */
03466 
03467   getopt_init();
03468   while((option = Getopt(argc, argv, format)) != -1)
03469     {
03470       switch (option)
03471         {
03472         case 'v':
03473           if(flag_v)
03474             fprintf(output,
03475                     "access: warning: option 'v' has been specified more than once.\n");
03476           else
03477             flag_v++;
03478           break;
03479 
03480         case 'h':
03481           if(flag_h)
03482             fprintf(output,
03483                     "access: warning: option 'h' has been specified more than once.\n");
03484           else
03485             flag_h++;
03486           break;
03487 
03488         default:
03489         case '?':
03490           fprintf(output, "access: unknown option : %c\n", Optopt);
03491           err_flag++;
03492           break;
03493         }
03494     }
03495 
03496   if(flag_h)
03497     {
03498       /* print usage */
03499       fprintf(output, help_flush_cache);
03500       return 0;
03501     }
03502 
03503   /* Exactly 1 args expected */
03504   if(Optind != (argc - 1))
03505     {
03506       err_flag++;
03507     }
03508   else
03509     {
03510       file = argv[Optind];
03511     }
03512 
03513   if(err_flag)
03514     {
03515       fprintf(output, help_flush_cache);
03516       return -1;
03517     }
03518 
03519   /* copy current absolute path to a local variable. */
03520   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
03521 
03522   /* retrieve handle to the file whose permissions are to be tested */
03523   if((rc =
03524      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
03525                      output)))
03526     return rc;
03527 
03528   if(obj_hdl->object.file.pentry_content == NULL)
03529     {
03530       fprintf(output, "Error: this entry is not data cached\n");
03531       return 1;
03532     }
03533 
03534   if(cache_content_flush(obj_hdl->object.file.pentry_content,
03535                          CACHE_CONTENT_FLUSH_AND_DELETE,
03536                          (cache_content_client_t *) context->client.pcontent_client,
03537                          &context->context,
03538                          &cache_content_status) != CACHE_CONTENT_SUCCESS)
03539     {
03540       fprintf(output, "Error executing cache_content_flush: %d\n", cache_content_status);
03541       return cache_content_status;
03542     }
03543 
03544   if(flag_v)
03545     {
03546       fprintf(output, "Entry %p has been flushed\n", obj_hdl);
03547     }
03548 
03549   return 0;
03550 }                               /* fn_Cache_inode_flush_cache */
03551 
03553 int fn_Cache_inode_read(int argc,       /* IN : number of args in argv */
03554                         char **argv,    /* IN : arg list               */
03555                         FILE * output /* IN : output stream          */ )
03556 {
03557   char format[] = "hvAXB:s:";
03558   int rc, option;
03559 
03560   int err_flag = 0;
03561   int flag_v = 0;
03562   int flag_h = 0;
03563   int flag_s = 0;
03564   int flag_A = 0;
03565   int flag_X = 0;
03566   int flag_B = 0;
03567 
03568   fsal_attrib_list_t fsal_attr;
03569 
03570   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
03571   cache_entry_t *obj_hdl;       /* handle of the object        */
03572 
03573   char str_seek_buff[256];
03574   char *str_seek_type = NULL;
03575   char *str_seek_offset = NULL;
03576   char *str_total_bytes = NULL;
03577   char *str_block_size = NULL;
03578 
03579   fsal_size_t block_size = 1024;        /* default: 1ko */
03580   fsal_size_t total_bytes = 0;  /* 0 == read all */
03581   fsal_seek_t seek_desc = { FSAL_SEEK_SET, 0 }; /* default: start of the file */
03582 
03583   /* fsal arguments */
03584 
03585   fsal_boolean_t is_eof = 0;
03586   fsal_size_t total_nb_read = 0;
03587   fsal_size_t once_nb_read = 0;
03588   fsal_size_t nb_block_read = 0;
03589 
03590   char *p_read_buff;
03591 
03592   char *file = NULL;            /* the relative path to the object */
03593 
03594   struct timeval timer_start;
03595   struct timeval timer_stop;
03596   struct timeval timer_diff;
03597 
03598   const char help_read[] =
03599       "Usage:\n"
03600       "  read [-h][-v][-A][-X] [-B <block_size> ] [ -s <seek_type>,<offset> ]  { <total_bytes> | all } filename\n"
03601       "Options:\n"
03602       "  -h: print this help\n"
03603       "  -v: verbose mode\n"
03604       "  -A: display read data in ascii\n"
03605       "  -X: display read data in hexa\n"
03606       "  -B <blocksize>: block size used for reading, in bytes (default 1k).\n"
03607       "  -s <seek_type>,<offset>: specify the position of the first byte to be read.\n"
03608       "        <seek_type> can take the values SET, CUR or END.\n"
03609       "        <offset> is a signed integer.\n"
03610       "  <total_bytes>: indicates the total number of bytes to be read\n"
03611       "      ('all' indicates that data are read until the end of the file).\n"
03612       "Example:\n"
03613       "  For reading the last 2kB of the opened file, using 1k block size:\n"
03614       "        read -B 1024 -s END,-2048 all  filename\n";
03615 
03616   cmdCacheInode_thr_info_t *context;
03617 
03618   /* is the fs initialized ? */
03619   if(!cache_init)
03620     {
03621       fprintf(output, "Error: Cache is not initialized\n");
03622       return -1;
03623     }
03624 
03625   context = RetrieveInitializedContext();
03626 
03627   /* analysing options */
03628   getopt_init();
03629 
03630   while((option = Getopt(argc, argv, format)) != -1)
03631     {
03632       switch (option)
03633         {
03634         case 'v':
03635           if(flag_v)
03636             fprintf(output,
03637                     "read: warning: option 'v' has been specified more than once.\n");
03638           else
03639             flag_v++;
03640           break;
03641 
03642         case 'h':
03643           if(flag_h)
03644             fprintf(output,
03645                     "read: warning: option 'h' has been specified more than once.\n");
03646           else
03647             flag_h++;
03648           break;
03649 
03650         case 'A':
03651           if(flag_A)
03652             fprintf(output,
03653                     "read: warning: option 'A' has been specified more than once.\n");
03654           else if(flag_X)
03655             {
03656               fprintf(output, "read: option 'A' conflicts with option 'X'.\n");
03657               err_flag++;
03658             }
03659           else
03660             flag_A++;
03661           break;
03662 
03663         case 'X':
03664           if(flag_X)
03665             fprintf(output,
03666                     "read: warning: option 'X' has been specified more than once.\n");
03667           else if(flag_A)
03668             {
03669               fprintf(output, "read: option 'X' conflicts with option 'A'.\n");
03670               err_flag++;
03671             }
03672           else
03673             flag_X++;
03674           break;
03675 
03676         case 'B':
03677           if(flag_B)
03678             fprintf(output,
03679                     "read: warning: option 'B' has been specified more than once.\n");
03680           else
03681             {
03682               flag_B++;
03683               str_block_size = Optarg;
03684             }
03685           break;
03686 
03687         case 's':
03688           if(flag_s)
03689             fprintf(output,
03690                     "read: warning: option 's' has been specified more than once.\n");
03691           else
03692             {
03693               flag_s++;
03694               strncpy(str_seek_buff, Optarg, 256);
03695               str_seek_type = str_seek_buff;
03696             }
03697           break;
03698 
03699         case '?':
03700           fprintf(output, "read: unknown option : %c\n", Optopt);
03701           err_flag++;
03702           break;
03703         }
03704     }
03705 
03706   if(flag_h)
03707     {
03708       /* print usage */
03709       fprintf(output, help_read);
03710       return 0;
03711     }
03712 
03713   /* Exactly 1 args expected */
03714   if(Optind != (argc - 2))
03715     {
03716       err_flag++;
03717     }
03718   else
03719     {
03720       str_total_bytes = argv[Optind];
03721       file = argv[Optind + 1];
03722     }
03723 
03724   if(err_flag)
03725     {
03726       fprintf(output, help_read);
03727       return -1;
03728     }
03729 
03730   /* copy current absolute path to a local variable. */
03731   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
03732 
03733   /* retrieve handle to the file whose permissions are to be tested */
03734   if((rc =
03735      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
03736                      output)))
03737     return rc;
03738 
03739   /* Sanity check */
03740   if(obj_hdl->type != REGULAR_FILE)
03741     {
03742       fprintf(output, "Error: This entry is no REGULAR_FILE\n");
03743       return 1;
03744     }
03745 
03746   /* Is this entry cached ? */
03747   if(obj_hdl->object.file.pentry_content == NULL)
03748     {
03749       if(flag_v)
03750         fprintf(output, "Warning: This entry is not data cached\n");
03751     }
03752 
03753   /* check argument types */
03754 
03755   if(flag_B)
03756     {
03757       /* Try to convert the str_block_size to fsal_size_t */
03758 
03759       rc = ato64(str_block_size, &block_size);
03760 
03761       if(rc == -1)
03762         {
03763           fprintf(output, "read: error: invalid block size \"%s\"\n", str_block_size);
03764           err_flag++;
03765         }
03766 
03767     }
03768 
03769   if(flag_s)
03770     {
03771       /* Try to parse the argument */
03772 
03773       str_seek_offset = strchr(str_seek_type, ',');
03774 
03775       if(str_seek_offset == NULL)
03776         {
03777           fprintf(output,
03778                   "read: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n",
03779                   str_seek_type);
03780           err_flag++;
03781         }
03782 
03783       if(!err_flag)
03784         {
03785           int sign = 1;
03786 
03787           *str_seek_offset = '\0';
03788           str_seek_offset++;    /* the first char after the "," */
03789 
03790           /* Check seek type */
03791 
03792           if(!strncmp(str_seek_type, "CUR", 256))
03793             seek_desc.whence = FSAL_SEEK_CUR;
03794           else if(!strncmp(str_seek_type, "SET", 256))
03795             seek_desc.whence = FSAL_SEEK_SET;
03796           else if(!strncmp(str_seek_type, "END", 256))
03797             seek_desc.whence = FSAL_SEEK_END;
03798           else
03799             {
03800               fprintf(output,
03801                       "read: error: invalid seek type \"%s\". CUR, SET or END expected.\n",
03802                       str_seek_type);
03803               err_flag++;
03804             }
03805 
03806           /* Try to convert str_seek_offset to fsal_off_t */
03807 
03808           switch (str_seek_offset[0])
03809             {
03810             case '+':
03811               sign = 1;
03812               str_seek_offset++;
03813               break;
03814 
03815             case '-':
03816               sign = -1;
03817               str_seek_offset++;
03818               break;
03819             }
03820 
03821           rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset);
03822 
03823           if(rc == -1)
03824             {
03825               fprintf(output, "read: error: invalid offset \"%s\".\n", str_seek_offset);
03826               err_flag++;
03827             }
03828           else if(sign < 0)
03829             seek_desc.offset = -seek_desc.offset;
03830 
03831         }
03832 
03833     }
03834   /* else default seeking : SET,0 */
03835 
03836   if(!strcasecmp(str_total_bytes, "all"))
03837     {
03838       total_bytes = 0;
03839     }
03840   else
03841     {
03842       rc = ato64(str_total_bytes, &total_bytes);
03843 
03844       if(rc == -1)
03845         {
03846           fprintf(output,
03847                   "read: error: invalid read size \"%s\". \"all\" or <nb_bytes> expected.\n",
03848                   str_total_bytes);
03849           err_flag++;
03850         }
03851     }
03852 
03853   if(err_flag)
03854     {
03855       fprintf(output, help_read);
03856       return -1;
03857     }
03858 
03859   if(flag_v)
03860     {
03861       /* print a sum-up of read parameters */
03862       fprintf(output,
03863               "Read options: Block size: %llu Bytes, Seek: %s%+lld, Read limit: %llu Bytes\n",
03864               block_size,
03865               (seek_desc.whence == FSAL_SEEK_SET ? "SET" : seek_desc.whence ==
03866                FSAL_SEEK_CUR ? "CUR" : "END"), (long long)seek_desc.offset, total_bytes);
03867     }
03868 
03869   /* Now all arguments have been parsed, let's act ! */
03870 
03871   /* alloc a buffer */
03872   p_read_buff = gsh_malloc(block_size);
03873 
03874   if(p_read_buff == NULL)
03875     {
03876       fprintf(output,
03877               "read: error: Not enough memory to allocate read buffer (%llu Bytes).\n",
03878               block_size);
03879       return ENOMEM;
03880     }
03881 
03882   gettimeofday(&timer_start, NULL);
03883 
03884   /* while EOF is not reached, and read<asked (when total_bytes!=0) */
03885   while(!is_eof && !((total_bytes != 0) && (total_nb_read >= total_bytes)))
03886     {
03887       if(cache_inode_rdwr(obj_hdl,
03888                           CACHE_INODE_READ,
03889                           &seek_desc,
03890                           block_size,
03891                           &once_nb_read,
03892                           &fsal_attr,
03893                           (caddr_t) p_read_buff,
03894                           &is_eof,
03895                           &context->client,
03896                           &context->context,
03897                           TRUE, &context->cache_status) != CACHE_INODE_SUCCESS)
03898         {
03899           log_fprintf(output, "Error executing cache_inode_read : %J%r\n",
03900                       ERR_CACHE_INODE, context->cache_status);
03901 
03902           return context->cache_status;
03903         }
03904 
03905       if(isFullDebug(COMPONENT_CACHE_INODE))
03906         {
03907           fprintf(output,
03908                   "shell: block_size=%llu, once_nb_read=%llu, total_bytes=%llu, total_nb_read=%llu, eof=%d, seek=%d.%"PRIu64,
03909                   block_size, once_nb_read, total_bytes, total_nb_read, is_eof,
03910                   seek_desc.whence, seek_desc.offset);
03911         }
03912 
03913       /* print what was read. */
03914       if(flag_A)
03915         {
03916           fsal_size_t index;
03917           for(index = 0; index < once_nb_read; index++)
03918             fprintf(output, "%c.", p_read_buff[index]);
03919         }
03920       else if(flag_X)
03921         {
03922           fsal_size_t index;
03923           for(index = 0; index < once_nb_read; index++)
03924             fprintf(output, "%.2X ", p_read_buff[index]);
03925         }
03926       else
03927         fprintf(output, ".");
03928 
03929       /* update stats */
03930 
03931       if(once_nb_read > 0)
03932         nb_block_read++;
03933 
03934       total_nb_read += once_nb_read;
03935 
03936       /* flush */
03937       if(nb_block_read % 10)
03938         fflush(output);
03939 
03940       /* Update the seek descriptor */
03941       seek_desc.whence = FSAL_SEEK_SET;
03942       seek_desc.offset += once_nb_read;
03943 
03944     }
03945 
03946   gettimeofday(&timer_stop, NULL);
03947 
03948   /* newline after read blocks */
03949   fprintf(output, "\n");
03950 
03951   if(flag_v)
03952     {
03953       double bandwidth;
03954 
03955       /* print stats */
03956       fprintf(output, "Nb blocks read: %llu\n", nb_block_read);
03957       fprintf(output, "Total: %llu Bytes\n", total_nb_read);
03958 
03959       fprintf(output, "Time enlapsed: ");
03960       timer_diff = time_diff(timer_start, timer_stop);
03961       print_timeval(output, timer_diff);
03962 
03963       bandwidth =
03964           total_nb_read / (1024 * 1024 *
03965                            (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec));
03966 
03967       fprintf(output, "Bandwidth: %f MB/s\n", bandwidth);
03968 
03969     }
03970   gsh_free(p_read_buff);
03971 
03972   return 0;
03973 }                               /* fn_Cache_inode_read */
03974 
03976 int fn_Cache_inode_write(int argc,      /* IN : number of args in argv */
03977                          char **argv,   /* IN : arg list               */
03978                          FILE * output /* IN : output stream          */ )
03979 {
03980   char format[] = "hvs:N:A:X:";
03981 
03982   int rc, option;
03983   int err_flag = 0;
03984 
03985   int flag_v = 0;
03986   int flag_h = 0;
03987   int flag_N = 0;
03988   int flag_s = 0;
03989   int flag_A = 0;
03990   int flag_X = 0;
03991 
03992   char *str_times = NULL;
03993   char str_seek_buff[256];
03994   char *str_seek_type = NULL;
03995   char *str_seek_offset = NULL;
03996 
03997   char *str_hexa = NULL;
03998   char *str_ascii = NULL;
03999 
04000   size_t datasize = 0;
04001   char *databuff = NULL;
04002 
04003   unsigned long long nb_times = 1;      /* default = 1 */
04004   fsal_u64_t nb_block_written = 0;
04005   fsal_size_t size_written = 0;
04006   fsal_size_t size_written_once = 0;
04007 
04008   fsal_size_t block_size = 1024;        /* default: 1ko */
04009   fsal_seek_t seek_desc = { FSAL_SEEK_SET, 0 }; /* default: start of the file */
04010 
04011   fsal_attrib_list_t fsal_attr;
04012 
04013   fsal_boolean_t fsal_eof;
04014 
04015   struct timeval timer_start;
04016   struct timeval timer_stop;
04017   struct timeval timer_diff;
04018 
04019   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
04020   cache_entry_t *obj_hdl;       /* handle of the object        */
04021 
04022   char *file = NULL;            /* the relative path to the object */
04023 
04024   const char help_write[] =
04025       "Usage:\n"
04026       "  write [-h][-v] [ -s <seek_type>,<offset> ]  [-N <nb_times>] -A <ascii_string> filename\n"
04027       "  write [-h][-v] [ -s <seek_type>,<offset> ]  [-N <nb_times>] -X <hexa_data> filename\n"
04028       "Where:\n"
04029       "  <seek_type> can be: SET, CUR, END\n"
04030       "  <offset> is a signed number of bytes.\n"
04031       "  <nb_times> is the number of times we write the expression into the file.\n"
04032       "\n"
04033       "  <ascii_string> is a string to be written to file.\n"
04034       "      Note that the null terminating character of is also written\n"
04035       "      to file.\n"
04036       "or\n"
04037       "  <hexa_data> is a data represented in hexadecimal format,\n"
04038       "      that is to be written to file.\n"
04039       "\n"
04040       "Examples:\n"
04041       "\n"
04042       "  For writing 10 times the null terminated string \"hello world\"\n"
04043       "  at the end of the file:\n"
04044       "        write -s END,0 -N 10 -A \"hello world\" filename\n"
04045       "\n"
04046       "  For overwriting the beginning of the file with\n"
04047       "  the pattern 0xA1267AEF31254ADE repeated twice:\n"
04048       "        write -s SET,0 -N 2 -X \"A1267AEF31254ADE\" filename\n";
04049 
04050   cmdCacheInode_thr_info_t *context;
04051 
04052   /* is the fs initialized ? */
04053   if(!cache_init)
04054     {
04055       fprintf(output, "Error: Cache is not initialized\n");
04056       return -1;
04057     }
04058 
04059   context = RetrieveInitializedContext();
04060 
04061   /* analysing options */
04062   getopt_init();
04063 
04064   while((option = Getopt(argc, argv, format)) != -1)
04065     {
04066       switch (option)
04067         {
04068         case 'v':
04069           if(flag_v)
04070             fprintf(output,
04071                     "write: warning: option 'v' has been specified more than once.\n");
04072           else
04073             flag_v++;
04074           break;
04075 
04076         case 'h':
04077           if(flag_h)
04078             fprintf(output,
04079                     "write: warning: option 'h' has been specified more than once.\n");
04080           else
04081             flag_h++;
04082           break;
04083 
04084         case 'N':
04085           if(flag_N)
04086             fprintf(output,
04087                     "write: warning: option 'N' has been specified more than once.\n");
04088           else
04089             {
04090               flag_N++;
04091               str_times = Optarg;
04092             }
04093           break;
04094 
04095         case 's':
04096           if(flag_s)
04097             fprintf(output,
04098                     "write: warning: option 's' has been specified more than once.\n");
04099           else
04100             {
04101               flag_s++;
04102               strncpy(str_seek_buff, Optarg, 256);
04103               str_seek_buff[255] = '\0';
04104               str_seek_type = str_seek_buff;
04105             }
04106           break;
04107 
04108         case 'A':
04109           if(flag_A)
04110             fprintf(output,
04111                     "write: warning: option 'A' has been specified more than once.\n");
04112           else if(flag_X)
04113             {
04114               fprintf(output, "write: option 'A' conflicts with option 'X'.\n");
04115               err_flag++;
04116             }
04117           else
04118             {
04119               flag_A++;
04120               str_ascii = Optarg;
04121             }
04122           break;
04123 
04124         case 'X':
04125           if(flag_X)
04126             fprintf(output,
04127                     "write: warning: option 'X' has been specified more than once.\n");
04128           else if(flag_A)
04129             {
04130               fprintf(output, "write: option 'X' conflicts with option 'A'.\n");
04131               err_flag++;
04132             }
04133           else
04134             {
04135               flag_X++;
04136               str_hexa = Optarg;
04137             }
04138           break;
04139 
04140         case '?':
04141           fprintf(output, "write: unknown option : %c\n", Optopt);
04142           err_flag++;
04143           break;
04144         }
04145     }
04146 
04147   if(flag_h)
04148     {
04149       /* print usage */
04150       fprintf(output, help_write);
04151       return 0;
04152     }
04153 
04154   /* Exactly 1 args expected */
04155   if(Optind != (argc - 1))
04156     {
04157       err_flag++;
04158     }
04159   else
04160     {
04161       file = argv[Optind];
04162     }
04163 
04164   if(err_flag)
04165     {
04166       fprintf(output, help_write);
04167       return -1;
04168     }
04169 
04170   /* copy current absolute path to a local variable. */
04171   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
04172   glob_path[FSAL_MAX_PATH_LEN - 1] = '\0';
04173 
04174   /* retrieve handle to the file whose permissions are to be tested */
04175   if((rc =
04176      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
04177                      output)))
04178     return rc;
04179 
04180   /* Sanity check */
04181   if(obj_hdl->type != REGULAR_FILE)
04182     {
04183       fprintf(output, "Error: This entry is no REGULAR_FILE\n");
04184       return 1;
04185     }
04186 
04187   /* Is this entry cached ? */
04188   if(obj_hdl->object.file.pentry_content == NULL)
04189     {
04190       if(flag_v)
04191         fprintf(output, "Warning: This entry is not data cached\n");
04192     }
04193 
04194   /* check argument types */
04195 
04196   if(flag_N)
04197     {
04198       /* Try to convert the str_times to nb_times */
04199 
04200       rc = ato64(str_times, &nb_times);
04201 
04202       if(rc == -1)
04203         {
04204           fprintf(output, "write: error: invalid number \"%s\"\n", str_times);
04205           return EINVAL;
04206         }
04207 
04208     }
04209 
04210   if(flag_s)
04211     {
04212       int sign = 1;
04213 
04214       /* Try to parse the argument */
04215 
04216       str_seek_offset = strchr(str_seek_type, ',');
04217 
04218       if(str_seek_offset == NULL)
04219         {
04220           fprintf(output,
04221                   "write: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n",
04222                   str_seek_type);
04223           return EINVAL;
04224         }
04225 
04226       *str_seek_offset = '\0';
04227       str_seek_offset++;        /* the first char after the "," */
04228 
04229       /* Check seek type */
04230 
04231       if(!strncmp(str_seek_type, "CUR", 256))
04232         seek_desc.whence = FSAL_SEEK_CUR;
04233       else if(!strncmp(str_seek_type, "SET", 256))
04234         seek_desc.whence = FSAL_SEEK_SET;
04235       else if(!strncmp(str_seek_type, "END", 256))
04236         seek_desc.whence = FSAL_SEEK_END;
04237       else
04238         {
04239           fprintf(output,
04240                   "write: error: invalid seek type \"%s\". CUR, SET or END expected.\n",
04241                   str_seek_type);
04242           return EINVAL;
04243         }
04244 
04245       /* Try to convert str_seek_offset to fsal_off_t */
04246 
04247       switch (str_seek_offset[0])
04248         {
04249         case '+':
04250           sign = 1;
04251           str_seek_offset++;
04252           break;
04253 
04254         case '-':
04255           sign = -1;
04256           str_seek_offset++;
04257           break;
04258         }
04259 
04260       rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset);
04261 
04262       if(rc == -1)
04263         {
04264           fprintf(output, "write: error: invalid offset \"%s\".\n", str_seek_offset);
04265           return EINVAL;
04266         }
04267       else if(sign < 0)
04268         seek_desc.offset = -seek_desc.offset;
04269 
04270     }
04271   /* else default seeking : SET,0 */
04272 
04273   if(flag_A)
04274     {
04275       datasize = strlen(str_ascii) + 1; /* Include null termination char. */
04276       databuff = str_ascii;
04277     }
04278 
04279   if(flag_X)
04280     {
04281       size_t length = strlen(str_hexa);
04282 
04283       datasize = (length >> 1);
04284 
04285       if(length % 2)
04286         {
04287 
04288           /* if it is not odd: error */
04289           fprintf(output,
04290                   "write: error: in \"%s\", data length is not a multiple of 8 bits.\n",
04291                   str_hexa);
04292 
04293           return EINVAL;
04294         }
04295 
04296       databuff = gsh_malloc(datasize + 1);
04297 
04298       if(databuff == NULL)
04299         {
04300           fprintf(output, "write: error: Not enough memory to allocate %llu Bytes.\n",
04301                   (unsigned long long)datasize);
04302           return ENOMEM;
04303         }
04304 
04305       memset(databuff, 0, datasize + 1);
04306 
04307       /* try to convert the string to hexa */
04308       rc = sscanmem(databuff, datasize, str_hexa);
04309 
04310       if(rc != (int)(2 * datasize))
04311         {
04312           /* if it is not odd: error */
04313           fprintf(output, "write: error: \"%s\" in not a valid hexa format.\n", str_hexa);
04314 
04315           gsh_malloc(str_hexa);
04316 
04317           return EINVAL;
04318         }
04319 
04320     }
04321 
04322   if(flag_v)
04323     {
04324       /* print a sum-up of write parameters */
04325       fprintf(output, "Write options: Data length: %llu x %llu Bytes, Seek: %s%+lld\n",
04326               (unsigned long long)nb_times,
04327               (unsigned long long)datasize,
04328               (seek_desc.whence == FSAL_SEEK_SET ? "SET" :
04329                seek_desc.whence == FSAL_SEEK_CUR ? "CUR" :
04330                "END"), (long long)seek_desc.offset);
04331     }
04332 
04333   /* variables initialisation */
04334 
04335   block_size = (fsal_size_t) datasize;
04336   nb_block_written = 0;
04337   size_written = 0;
04338   size_written_once = 0;
04339 
04340   gettimeofday(&timer_start, NULL);
04341 
04342   /* write loop */
04343 
04344   while(nb_block_written < nb_times)
04345     {
04346       if(cache_inode_rdwr(obj_hdl,
04347                           CACHE_INODE_WRITE,
04348                           &seek_desc,
04349                           block_size,
04350                           &size_written_once,
04351                           &fsal_attr,
04352                           (caddr_t) databuff,
04353                           &fsal_eof,
04354                           &context->client,
04355                           &context->context,
04356                           TRUE, &context->cache_status) != CACHE_INODE_SUCCESS)
04357         {
04358           log_fprintf(output, "Error executing cache_inode_write : %J%r\n",
04359                       ERR_CACHE_INODE, context->cache_status);
04360 
04361           return context->cache_status;
04362         }
04363 
04364       fprintf(output, ".");
04365 
04366       /* update stats */
04367 
04368       if(size_written_once > 0)
04369         nb_block_written++;
04370 
04371       size_written += size_written_once;
04372 
04373       /* flush */
04374       if(nb_block_written % 10)
04375         fflush(output);
04376 
04377       /* Update the seek descriptor */
04378       seek_desc.whence = FSAL_SEEK_SET;
04379       seek_desc.offset += size_written_once;
04380     }
04381 
04382   gettimeofday(&timer_stop, NULL);
04383 
04384   /* newline after written blocks */
04385   fprintf(output, "\n");
04386 
04387   if(flag_v)
04388     {
04389       double bandwidth;
04390 
04391       /* print stats */
04392       fprintf(output, "Nb blocks written: %llu\n", nb_block_written);
04393       fprintf(output, "Total volume: %llu Bytes\n", size_written);
04394 
04395       fprintf(output, "Time enlapsed: ");
04396       timer_diff = time_diff(timer_start, timer_stop);
04397       print_timeval(output, timer_diff);
04398 
04399       bandwidth =
04400           size_written / (1024 * 1024 *
04401                           (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec));
04402 
04403       fprintf(output, "Bandwidth: %f MB/s\n", bandwidth);
04404 
04405     }
04406 
04407   if(flag_X)
04408     gsh_free(databuff);
04409 
04410   return 0;
04411 }                               /* fn_Cache_inode_write */
04412 
04414 int fn_Cache_inode_su(int argc, /* IN : number of args in argv */
04415                       char **argv,      /* IN : arg list               */
04416                       FILE * output)    /* IN : output stream          */
04417 {
04418 
04419   char *str_uid;
04420   uid_t uid;
04421   fsal_status_t st;
04422   struct passwd *pw_struct;
04423   int i;
04424 
04425 # define MAX_GRPS  128
04426   gid_t groups_tab[MAX_GRPS];
04427   int nb_grp;
04428 
04429   const char help_su[] = "usage: su <uid>\n";
04430 
04431   cmdCacheInode_thr_info_t *context;
04432 
04433   /* is the fs initialized ? */
04434   if(!cache_init)
04435     {
04436       fprintf(output, "Error: Cache is not initialized\n");
04437       return -1;
04438     }
04439 
04440   context = RetrieveInitializedContext();
04441 
04442   /* UID arg expected */
04443   if(argc != 2)
04444     {
04445       fprintf(output, help_su);
04446       return -1;
04447     }
04448   else
04449     {
04450       str_uid = argv[1];
04451     }
04452 
04453   if(isdigit(str_uid[0]))
04454     {
04455       if((uid = my_atoi(str_uid)) == (uid_t) - 1)
04456         {
04457           fprintf(output, "Error: invalid uid \"%s\"\n", str_uid);
04458           return -1;
04459         }
04460       pw_struct = getpwuid(uid);
04461     }
04462   else
04463     {
04464       pw_struct = getpwnam(str_uid);
04465     }
04466 
04467   if(pw_struct == NULL)
04468     {
04469       fprintf(output, "Unknown user %s\n", str_uid);
04470       return errno;
04471     }
04472 
04473   nb_grp = getugroups(MAX_GRPS, groups_tab, pw_struct->pw_name, pw_struct->pw_gid);
04474 
04475   fprintf(output, "Changing user to : %s ( uid = %d, gid = %d )\n",
04476           pw_struct->pw_name, pw_struct->pw_uid, pw_struct->pw_gid);
04477 
04478   if(nb_grp > 1)
04479     {
04480       fprintf(output, "altgroups = ");
04481       for(i = 1; i < nb_grp; i++)
04482         {
04483           if(i == 1)
04484             fprintf(output, "%d", groups_tab[i]);
04485           else
04486             fprintf(output, ", %d", groups_tab[i]);
04487         }
04488       fprintf(output, "\n");
04489     }
04490 
04491   st = FSAL_GetClientContext(&context->context, &context->exp_context,
04492                              pw_struct->pw_uid, pw_struct->pw_gid, groups_tab, nb_grp);
04493 
04494   if(FSAL_IS_ERROR(st))
04495     {
04496       fprintf(output, "Error executing FSAL_GetUserCred:");
04497       print_fsal_status(output, st);
04498       fprintf(output, "\n");
04499       return st.major;
04500     }
04501 
04502   fprintf(output, "Done.\n");
04503 
04504   return 0;
04505 
04506 }
04507 
04509 int fn_Cache_inode_open_by_name(int argc,       /* IN : number of args in argv */
04510                                 char **argv,    /* IN : arg list               */
04511                                 FILE * output)  /* IN : output stream          */
04512 {
04513   char glob_path[FSAL_MAX_PATH_LEN];
04514 
04515   cache_entry_t *pentry_file;
04516   fsal_attrib_list_t file_attr;
04517   fsal_status_t st;
04518   fsal_name_t filename;
04519 
04520   cmdCacheInode_thr_info_t *context;
04521 
04522   const char help_cd[] = "usage: open_by_name <path> \n";
04523 
04524   if(!cache_init)
04525     {
04526       fprintf(output, "\tCache is not initialized\n");
04527       return -1;
04528     }
04529 
04530   /* Exactly two arg expected */
04531   if(argc != 2)
04532     {
04533       fprintf(output, help_cd);
04534       return -1;
04535     }
04536 
04537   /* Convert filename to fsal_name_t */
04538   if(FSAL_IS_ERROR(st = FSAL_str2name(argv[1], FSAL_MAX_PATH_LEN, &filename)))
04539     {
04540       fprintf(output, "Error executing FSAL_str2name:\n");
04541       print_fsal_status(output, st);
04542       fprintf(output, "\n");
04543       return st.major;
04544 
04545       return -1;
04546     }
04547 
04548   context = RetrieveInitializedContext();
04549 
04550   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
04551   glob_path[FSAL_MAX_PATH_LEN - 1] = '\0';
04552 
04553   if((pentry_file = cache_inode_lookup(context->pentry,
04554                                        &filename,
04555                                        cachepol,
04556                                        &file_attr,
04557                                        &context->client,
04558                                        &context->context,
04559                                        &context->cache_status)) == NULL)
04560     {
04561       fprintf(output, "Error: cannot lookup %s in %s : %u\n", argv[1], glob_path,
04562               context->cache_status);
04563       return -1;
04564     }
04565 
04566   if((context->cache_status = cache_inode_open_by_name(context->pentry,
04567                                                        &filename,
04568                                                        pentry_file,
04569                                                        &context->client,
04570                                                        FSAL_O_RDWR,
04571                                                        &context->context,
04572                                                        &context->cache_status)) !=
04573      CACHE_INODE_SUCCESS)
04574     {
04575       log_fprintf(output, "Error executing cache_inode_open_by_name : %J%r\n",
04576                   ERR_CACHE_INODE, context->cache_status);
04577       return context->cache_status;
04578     }
04579 
04580   return 0;
04581 }
04582 
04584 int fn_Cache_inode_close(int argc,      /* IN : number of args in argv */
04585                          char **argv,   /* IN : arg list               */
04586                          FILE * output /* IN : output stream          */ )
04587 {
04588   char format[] = "hv";
04589 
04590   const char help_flush_cache[] =
04591       "usage: flush_close [-h][-v]  <path>\n"
04592       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
04593 
04594   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
04595   cache_entry_t *obj_hdl;       /* handle of the object        */
04596 
04597   int rc, option;
04598   int flag_v = 0;
04599   int flag_h = 0;
04600   int err_flag = 0;
04601 
04602   char *file = NULL;            /* the relative path to the object */
04603 
04604   cmdCacheInode_thr_info_t *context;
04605 
04606 
04607   /* is the fs initialized ? */
04608   if(!cache_init)
04609     {
04610       fprintf(output, "Error: Cache is not initialized\n");
04611       return -1;
04612     }
04613 
04614   context = RetrieveInitializedContext();
04615 
04616   /* analysing options */
04617 
04618   getopt_init();
04619   while((option = Getopt(argc, argv, format)) != -1)
04620     {
04621       switch (option)
04622         {
04623         case 'v':
04624           if(flag_v)
04625             fprintf(output,
04626                     "access: warning: option 'v' has been specified more than once.\n");
04627           else
04628             flag_v++;
04629           break;
04630 
04631         case 'h':
04632           if(flag_h)
04633             fprintf(output,
04634                     "access: warning: option 'h' has been specified more than once.\n");
04635           else
04636             flag_h++;
04637           break;
04638 
04639         default:
04640         case '?':
04641           fprintf(output, "access: unknown option : %c\n", Optopt);
04642           err_flag++;
04643           break;
04644         }
04645     }
04646 
04647   if(flag_h)
04648     {
04649       /* print usage */
04650       fprintf(output, help_flush_cache);
04651       return 0;
04652     }
04653 
04654   /* Exactly 1 args expected */
04655   if(Optind != (argc - 1))
04656     {
04657       err_flag++;
04658     }
04659   else
04660     {
04661       file = argv[Optind];
04662     }
04663 
04664   if(err_flag)
04665     {
04666       fprintf(output, help_flush_cache);
04667       return -1;
04668     }
04669 
04670   /* copy current absolute path to a local variable. */
04671   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
04672   glob_path[FSAL_MAX_PATH_LEN - 1] = '\0';
04673 
04674   /* retrieve handle to the file whose permissions are to be tested */
04675   if((rc =
04676      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
04677                      output)))
04678     return rc;
04679 
04680   if(obj_hdl->object.file.pentry_content == NULL)
04681     {
04682       fprintf(output, "Error: this entry is not data cached\n");
04683       return 1;
04684     }
04685 #ifdef _TOTO
04686   if(cache_content_flush(obj_hdl->object.file.pentry_content,
04687                          CACHE_CONTENT_FLUSH_AND_DELETE,
04688                          (cache_content_client_t *) context->client.pcontent_client,
04689                          &context->context,
04690                          &cache_content_status) != CACHE_CONTENT_SUCCESS)
04691     {
04692       fprintf(output, "Error executing cache_content_flush: %d\n", cache_content_status);
04693       return cache_content_status;
04694     }
04695 #endif
04696   fprintf(output, "not implemented yet\n");
04697 
04698   if(flag_v)
04699     {
04700       fprintf(output, "Entry %p has been flushed\n", obj_hdl);
04701     }
04702 
04703   return 0;
04704 }                               /* fn_Cache_inode_close */
04705 
04707 int fn_Cache_inode_invalidate(int argc,      /* IN : number of args in argv */
04708                               char **argv,   /* IN : arg list               */
04709                               FILE * output /* IN : output stream          */ )
04710 {
04711   char format[] = "hv";
04712 
04713   const char help_invalidate[] =
04714       "usage: invalidate [-h][-v]  <path>\n"
04715       "\n" "   -h : print this help\n" "   -v : verbose mode\n";
04716 
04717   char glob_path[FSAL_MAX_PATH_LEN];    /* absolute path of the object */
04718   cache_entry_t *obj_hdl;       /* handle of the object        */
04719 
04720   int rc, option;
04721   int flag_v = 0;
04722   int flag_h = 0;
04723   int err_flag = 0;
04724 
04725   char *file = NULL;            /* the relative path to the object */
04726 
04727   cmdCacheInode_thr_info_t *context;
04728 
04729   fsal_handle_t * pfsal_handle = NULL ;
04730 
04731   /* is the fs initialized ? */
04732   if(!cache_init)
04733     {
04734       fprintf(output, "Error: Cache is not initialized\n");
04735       return -1;
04736     }
04737 
04738   context = RetrieveInitializedContext();
04739 
04740   /* analysing options */
04741 
04742   getopt_init();
04743   while((option = Getopt(argc, argv, format)) != -1)
04744     {
04745       switch (option)
04746         {
04747         case 'v':
04748           if(flag_v)
04749             fprintf(output,
04750                     "access: warning: option 'v' has been specified more than once.\n");
04751           else
04752             flag_v++;
04753           break;
04754 
04755         case 'h':
04756           if(flag_h)
04757             fprintf(output,
04758                     "access: warning: option 'h' has been specified more than once.\n");
04759           else
04760             flag_h++;
04761           break;
04762 
04763         default:
04764         case '?':
04765           fprintf(output, "access: unknown option : %c\n", Optopt);
04766           err_flag++;
04767           break;
04768         }
04769     }
04770 
04771   if(flag_h)
04772     {
04773       /* print usage */
04774       fprintf(output, help_invalidate);
04775       return 0;
04776     }
04777 
04778   /* Exactly 1 args expected */
04779   if(Optind != (argc - 1))
04780     {
04781       err_flag++;
04782     }
04783   else
04784     {
04785       file = argv[Optind];
04786     }
04787 
04788   if(err_flag)
04789     {
04790       fprintf(output, help_invalidate);
04791       return -1;
04792     }
04793 
04794   if(flag_h)
04795     {
04796       /* print usage */
04797       fprintf(output, help_invalidate);
04798       return 0;
04799     }
04800 
04801   /* copy current absolute path to a local variable. */
04802   strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN);
04803   glob_path[FSAL_MAX_PATH_LEN - 1] = '\0';
04804 
04805   /* retrieve handle to the file whose permissions are to be tested */
04806   if((rc =
04807      cache_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->pentry, &obj_hdl,
04808                      output)))
04809     return rc;
04810 
04811   if((obj_hdl->type == UNASSIGNED) ||
04812      (obj_hdl->type == RECYCLED))
04813     {
04814       fprintf(output, "invalidate: unknown pentry type : %u\n",  obj_hdl->type );
04815       return -1 ;
04816     }
04817   pfsal_handle = &obj_hdl->handle;
04818 
04819   if( ( context->cache_status = cache_inode_invalidate( pfsal_handle,
04820                                                         &context->client,
04821                                                         &context->cache_status) ) != CACHE_INODE_SUCCESS )
04822     {
04823       fprintf(output, "Error executing cache_inode_invalidate: %d\n", context->cache_status);
04824       return -1 ;
04825     }
04826 
04827   if(flag_v)
04828     {
04829       fprintf(output, "Entry %p has been invalidated\n", obj_hdl);
04830     }
04831 
04832   return 0;
04833 }                               /* fn_Cache_inode_invalidate */