nfs-ganesha 1.4

fsal_dirs.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fsal.h"
00018 #include "fsal_internal.h"
00019 #include "fsal_convert.h"
00020 #include "HPSSclapiExt/hpssclapiext.h"
00021 #include <string.h>
00022 #include "abstract_mem.h"
00023 
00048 fsal_status_t HPSSFSAL_opendir(hpssfsal_handle_t * dir_handle,  /* IN */
00049                                hpssfsal_op_context_t * p_context,       /* IN */
00050                                hpssfsal_dir_t * dir_descriptor, /* OUT */
00051                                fsal_attrib_list_t * dir_attributes      /* [ IN/OUT ] */
00052     )
00053 {
00054   int rc;
00055   fsal_status_t st;
00056 
00057   /* sanity checks
00058    * note : dir_attributes is optionnal.
00059    */
00060   if(!dir_handle || !p_context || !dir_descriptor)
00061     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);
00062 
00063   /* Test access rights for this directory
00064    * and retrieve asked attributes */
00065 
00066   st = HPSSFSAL_access(dir_handle, p_context, FSAL_R_OK, dir_attributes);
00067 
00068   if(FSAL_IS_ERROR(st))
00069     Return(st.major, st.minor, INDEX_FSAL_opendir);
00070 
00071   /* if everything is OK, fills the dir_desc structure */
00072   memcpy(&dir_descriptor->dir_handle, dir_handle, sizeof(hpssfsal_handle_t));
00073   memcpy(&dir_descriptor->context, p_context, sizeof(hpssfsal_op_context_t));
00074 
00075   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);
00076 
00077 }
00078 
00115 fsal_status_t HPSSFSAL_readdir(hpssfsal_dir_t * dir_descriptor, /* IN */
00116                                hpssfsal_cookie_t start_position,        /* IN */
00117                                fsal_attrib_mask_t get_attr_mask,        /* IN */
00118                                fsal_mdsize_t buffersize,        /* IN */
00119                                fsal_dirent_t * pdirent, /* OUT */
00120                                hpssfsal_cookie_t * end_position,        /* OUT */
00121                                fsal_count_t * nb_entries,       /* OUT */
00122                                fsal_boolean_t * end_of_dir      /* OUT */ )
00123 {
00124   int rc, returned, i;
00125   fsal_status_t st;
00126 
00127   fsal_attrib_mask_t handle_attr_mask;
00128   fsal_count_t current_nb_entries, missing_entries, max_dir_entries;
00129 
00130   /* hpss_ReadRawAttrsHandle arguments. */
00131 
00132   u_signed64 curr_start_position;
00133   unsigned32 buff_size_in;
00134   unsigned32 bool_getattr_in;
00135   unsigned32 bool_eod_out;
00136   u_signed64 last_offset_out;
00137   //ns_DirEntry_t outbuff[FSAL_READDIR_SIZE];
00138   ns_DirEntry_t * outbuff = NULL ;
00139 
00140   /* sanity checks */
00141 
00142   if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir)
00143     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00144 
00145   if((outbuff = gsh_calloc(FSAL_READDIR_SIZE, sizeof(ns_DirEntry_t))) == NULL)
00146     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00147 
00148   /* handle provides : suppattr, type, fileid */
00151   handle_attr_mask = FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE | FSAL_ATTR_FILEID;
00152 
00153   /* if the handle cannot provide the requested attributes,
00154    * we have to retrieve file attributes. */
00155 
00156   if(get_attr_mask & (~handle_attr_mask))
00157     bool_getattr_in = TRUE;
00158   else
00159     bool_getattr_in = FALSE;
00160 
00161   /* init values */
00162 
00163   curr_start_position = start_position.data;
00164   bool_eod_out = 0;
00165   current_nb_entries = 0;
00166   max_dir_entries = (buffersize / sizeof(fsal_dirent_t));
00167 
00168   /* while we haven't filled the output buffer
00169    * and the end of dir has not been reached :
00170    */
00171   while((current_nb_entries < max_dir_entries) && (!bool_eod_out))
00172     {
00173 
00174       missing_entries = max_dir_entries - current_nb_entries;
00175 
00176       /* If the requested count is smaller than the default FSAL_READDIR_SIZE,
00177        * we use a smaller output buffer.
00178        */
00179       if(missing_entries < FSAL_READDIR_SIZE)
00180         buff_size_in = missing_entries * sizeof(ns_DirEntry_t);
00181       else
00182         buff_size_in = FSAL_READDIR_SIZE * sizeof(ns_DirEntry_t);
00183 
00184       /* call to hpss clapi */
00185 
00186       TakeTokenFSCall();
00187 
00188       rc = HPSSFSAL_ReadRawAttrsHandle(&(dir_descriptor->dir_handle.data.ns_handle),
00189                                        curr_start_position,
00190                                        &dir_descriptor->context.credential.hpss_usercred,
00191                                        buff_size_in,
00192                                        bool_getattr_in,
00193                                        ReturnInconsistentDirent,
00194                                        &bool_eod_out, &last_offset_out, outbuff);
00195 
00196       ReleaseTokenFSCall();
00197 
00198       if(rc < 0)
00199        {
00200          gsh_free( outbuff ) ;
00201          Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_readdir);
00202        }
00203       else
00204         returned = rc;
00205 
00206       /* Fills the fsal dirent list. */
00207 
00208       for(i = 0; i < returned; i++)
00209         {
00210 
00211           memset( (char *)&(pdirent[current_nb_entries].handle), 0, sizeof( hpssfsal_handle_t ) ) ;
00212           pdirent[current_nb_entries].handle.data.ns_handle = outbuff[i].ObjHandle;
00213 
00214           pdirent[current_nb_entries].handle.data.obj_type =
00215               hpss2fsal_type(outbuff[i].ObjHandle.Type);
00216 
00217           st = FSAL_str2name((char *)outbuff[i].Name, HPSS_MAX_FILE_NAME,
00218                              &pdirent[current_nb_entries].name);
00219 
00222           pdirent[current_nb_entries].cookie.data = outbuff[i].ObjOffset;
00223 
00224           /* set asked attributes */
00225           pdirent[current_nb_entries].attributes.asked_attributes = get_attr_mask;
00226 
00227           if(bool_getattr_in)
00228             {
00229 
00230               /* convert HPSS attributes to fsal attributes */
00231               st = hpss2fsal_attributes(&outbuff[i].ObjHandle,
00232                                         &outbuff[i].Attrs,
00233                                         &pdirent[current_nb_entries].attributes);
00234 
00235               /* on error, we set a special bit in the mask. */
00236               if(FSAL_IS_ERROR(st))
00237                 {
00238                   FSAL_CLEAR_MASK(pdirent[current_nb_entries].attributes.
00239                                   asked_attributes);
00240                   FSAL_SET_MASK(pdirent[current_nb_entries].attributes.asked_attributes,
00241                                 FSAL_ATTR_RDATTR_ERR);
00242                 }
00243 
00244             }
00245           else if(get_attr_mask)
00246             {
00247 
00248               /* extract asked attributes from file handle */
00249               st = hpssHandle2fsalAttributes(&outbuff[i].ObjHandle,
00250                                              &pdirent[current_nb_entries].attributes);
00251 
00252               /* on error, we set a special bit in the mask. */
00253               if(FSAL_IS_ERROR(st))
00254                 {
00255                   FSAL_CLEAR_MASK(pdirent[current_nb_entries].attributes.
00256                                   asked_attributes);
00257                   FSAL_SET_MASK(pdirent[current_nb_entries].attributes.asked_attributes,
00258                                 FSAL_ATTR_RDATTR_ERR);
00259                 }
00260 
00261             }
00262 
00263           /* set the previous' next */
00264           if(current_nb_entries)
00265             pdirent[current_nb_entries - 1].nextentry = &(pdirent[current_nb_entries]);
00266 
00267           /* current's next */
00268           pdirent[current_nb_entries].nextentry = NULL;
00269 
00270           /* increment entries count */
00271           current_nb_entries++;
00272           curr_start_position = last_offset_out;
00273         }
00274 
00275     }
00276 
00277   /* At this point, 2 cases :
00278    * - the requested count is reached
00279    * - the end of dir is reached.
00280    * However, the treatment is the same.
00281    */
00282 
00283   /* setting output vars. */
00284 
00285   /* if no item was read, the offset keeps the same. */
00286   end_position->data = (current_nb_entries == 0 ? start_position.data : last_offset_out);
00287 
00288   *nb_entries = current_nb_entries;
00289   *end_of_dir = (bool_eod_out ? TRUE : FALSE);
00290 
00291   LogDebug(COMPONENT_FSAL, "%s() returned %u entries, end_of_dir=%d", __func__, *nb_entries, *end_of_dir);
00292 
00293   gsh_free( outbuff ) ;
00294   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); /* @todo badly set fsal_log ? */
00295 }
00296 
00310 fsal_status_t HPSSFSAL_closedir(hpssfsal_dir_t * dir_descriptor /* IN */
00311     )
00312 {
00313 
00314   int rc;
00315 
00316   /* sanity checks */
00317   if(!dir_descriptor)
00318     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir);
00319 
00320   /* fill dir_descriptor with zeros */
00321   memset(dir_descriptor, 0, sizeof(hpssfsal_dir_t));
00322 
00323   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_closedir);
00324 
00325 }