nfs-ganesha 1.4

fsal_dirs.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #ifdef _SOLARIS
00019 #include "solaris_port.h"
00020 #endif                          /* _SOLARIS */
00021 
00022 #include <string.h>
00023 #ifdef _USE_GSSRPC
00024 #include <gssrpc/rpc.h>
00025 #include <gssrpc/xdr.h>
00026 #else
00027 #include <rpc/rpc.h>
00028 #include <rpc/xdr.h>
00029 #endif
00030 #include "nfs4.h"
00031 
00032 #include "abstract_mem.h"
00033 #include "fsal_internal.h"
00034 #include "fsal_convert.h"
00035 #include "fsal_common.h"
00036 
00037 #include "nfs_proto_functions.h"
00038 #include "fsal_nfsv4_macros.h"
00039 
00064 fsal_status_t PROXYFSAL_opendir(fsal_handle_t * dir_handle,        /* IN */
00065                                 fsal_op_context_t * p_context,     /* IN */
00066                                 fsal_dir_t * dir_desc,       /* OUT */
00067                                 fsal_attrib_list_t * dir_attributes     /* [ IN/OUT ] */
00068     )
00069 {
00070   proxyfsal_dir_t * dir_descriptor = (proxyfsal_dir_t *)dir_desc;
00071 
00072   /* sanity checks
00073    * note : dir_attributes is optional.
00074    */
00075   if(!dir_handle || !p_context || !dir_descriptor)
00076     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);
00077 
00078   PRINT_HANDLE("FSAL_opendir", dir_handle);
00079 
00080   /* Set the context */
00081   memcpy(&dir_descriptor->fhandle, dir_handle, sizeof(dir_descriptor->fhandle));
00082   memset(dir_descriptor->verifier, 0, NFS4_VERIFIER_SIZE);
00083   dir_descriptor->pcontext = (proxyfsal_op_context_t *)p_context;
00084 
00085   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);
00086 
00087 }
00088 
00125 fsal_status_t PROXYFSAL_readdir(fsal_dir_t * dir_desc,       /* IN */
00126                                 fsal_cookie_t start_pos,      /* IN */
00127                                 fsal_attrib_mask_t get_attr_mask,       /* IN */
00128                                 fsal_mdsize_t buffersize,       /* IN */
00129                                 fsal_dirent_t * pdirent,        /* OUT */
00130                                 fsal_cookie_t * end_position,      /* OUT */
00131                                 fsal_count_t * nb_entries,      /* OUT */
00132                                 fsal_boolean_t * end_of_dir     /* OUT */
00133     )
00134 {
00135   nfs_fh4 nfs4fh;
00136   bitmap4 bitmap;
00137   uint32_t bitmap_val[2];
00138   count4 nbreaddir;
00139   int rc = 0;
00140   int i = 0;
00141   int cpt = 0;
00142   entry4 *piter_entry = NULL;
00143   struct proxy_entry4 {
00144         entry4 e4;
00145         char name[MAXNAMLEN];
00146         fsal_proxy_internal_fattr_readdir_t attr;
00147         uint32_t bitmap[2];
00148   } *pxy_e4;
00149   struct timeval timeout = TIMEOUTRPC;
00150 #define FSAL_READDIR_NB_OP_ALLOC 2
00151   nfs_argop4 argoparray[FSAL_READDIR_NB_OP_ALLOC];
00152   nfs_resop4 resoparray[FSAL_READDIR_NB_OP_ALLOC];
00153   COMPOUND4args argnfs4;
00154   COMPOUND4res resnfs4;
00155   proxyfsal_dir_t * dir_descriptor = (proxyfsal_dir_t *)dir_desc;
00156   proxyfsal_cookie_t start_position;
00157 
00158   /* sanity checks */
00159 
00160   if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir)
00161     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00162 
00163   /* How much data should I read ? */
00164   nbreaddir = buffersize / (sizeof(fsal_dirent_t));
00165   if(nbreaddir > FSAL_READDIR_SIZE)
00166     nbreaddir = FSAL_READDIR_SIZE;
00167 
00168   pxy_e4 = gsh_calloc(nbreaddir, sizeof(*pxy_e4));
00169   if(pxy_e4 == NULL)
00170    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00171 
00172   memcpy(&start_position.data, &start_pos.data, sizeof( nfs_cookie4));
00173 
00174   LogFullDebug(COMPONENT_FSAL, "---> Readdir Offset=%llu sizeof(entry4)=%lu sizeof(fsal_dirent_t)=%lu \n",
00175                (unsigned long long)start_position.data, sizeof(entry4), sizeof(fsal_dirent_t));
00176 
00177   /* >> retrieve root handle filehandle here << */
00178   bitmap.bitmap4_len = 2;
00179   bitmap.bitmap4_val = bitmap_val;
00180   fsal_internal_proxy_create_fattr_readdir_bitmap(&bitmap);
00181 
00182   /* Setup results structures */
00183   argnfs4.argarray.argarray_val = argoparray;
00184   resnfs4.resarray.resarray_val = resoparray;
00185   argnfs4.minorversion = 0;
00186   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readdir" ; */
00187   argnfs4.tag.utf8string_val = NULL;
00188   argnfs4.tag.utf8string_len = 0;
00189   argnfs4.argarray.argarray_len = 0;
00190 
00191 #define FSAL_READDIR_IDX_OP_PUTFH      0
00192 #define FSAL_READDIR_IDX_OP_READDIR    1
00193 
00194   /* Set up reply structure */
00195   resnfs4.resarray.resarray_val = resoparray;
00196 
00197   for(i = 0; i < nbreaddir; i++)
00198     {
00199       fsal_internal_proxy_setup_readdir_fattr(&pxy_e4[i].attr);
00200 
00201       pxy_e4[i].e4.name.utf8string_val = pxy_e4[i].name;
00202       pxy_e4[i].e4.name.utf8string_len = sizeof(pxy_e4[i].name);
00203 
00204       pxy_e4[i].e4.attrs.attr_vals.attrlist4_val = (char *)&(pxy_e4[i].attr);
00205       pxy_e4[i].e4.attrs.attr_vals.attrlist4_len = sizeof(pxy_e4[i].attr);
00206 
00207       pxy_e4[i].e4.attrs.attrmask.bitmap4_val = pxy_e4[i].bitmap;
00208       pxy_e4[i].e4.attrs.attrmask.bitmap4_len = 2;
00209 
00210       pxy_e4[i].e4.nextentry = &pxy_e4[i+1].e4; /* Last one cleared after the loop */
00211     }
00212   pxy_e4[i-1].e4.nextentry = NULL;
00213   resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
00214       READDIR4res_u.resok4.reply.entries = &pxy_e4->e4;
00215 
00216   /* >> Call your filesystem lookup function here << */
00217   if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &dir_descriptor->fhandle) == FALSE)
00218    {
00219     gsh_free(pxy_e4);
00220     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00221    }
00223   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00224   COMPOUNDV4_ARG_ADD_OP_READDIR(argnfs4, start_position.data, nbreaddir,
00225                                 dir_descriptor->verifier, bitmap);
00226 
00227   TakeTokenFSCall();
00228   /* Call the NFSv4 function */
00229   COMPOUNDV4_EXECUTE(dir_descriptor->pcontext, argnfs4, resnfs4, rc);
00230   ReleaseTokenFSCall();
00231   if(rc != RPC_SUCCESS)
00232     {
00233 
00234       gsh_free(pxy_e4) ;
00235       Return(ERR_FSAL_IO, rc, INDEX_FSAL_readdir);
00236     }
00237 
00238   if(resnfs4.status != NFS4_OK)
00239     {
00240       gsh_free(pxy_e4);
00241       return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readdir);
00242     }
00243 
00244   /* Set the reply structure */
00245   if(resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
00246      READDIR4res_u.resok4.reply.eof == TRUE)
00247     {
00248       *end_of_dir = TRUE;
00249     }
00250 
00251   /* until the requested count is reached
00252    * or the end of dir is reached...
00253    */
00254 
00255   /* Don't forget setting output vars : end_position, nb_entries, end_of_dir  */
00256   for(piter_entry =
00257       resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
00258       READDIR4res_u.resok4.reply.entries; piter_entry != NULL;
00259       piter_entry = piter_entry->nextentry)
00260     {
00261       if(proxy_Fattr_To_FSAL_attr(&pdirent[cpt].attributes,
00262                                   (proxyfsal_handle_t *) &(pdirent[cpt].handle), &(piter_entry->attrs)) != 1)
00263         {
00264           FSAL_CLEAR_MASK(pdirent[cpt].attributes.asked_attributes);
00265           FSAL_SET_MASK(pdirent[cpt].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);
00266 
00267           gsh_free(pxy_e4);
00268           Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00269         }
00270 
00271       if(fsal_internal_proxy_fsal_utf8_2_name(&(pdirent[cpt].name),
00272                                               &(piter_entry->name)) == FALSE)
00273         {
00274           gsh_free(pxy_e4);
00275           Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00276         }
00277 
00278       pdirent[cpt].cookie.data = piter_entry->cookie;
00279       /* Link the entries together */
00280       pdirent[cpt].nextentry = NULL;    /* Will be overwritten if there is an entry behind, stay NULL if not */
00281       if(cpt != 0)
00282         pdirent[cpt - 1].nextentry = &pdirent[cpt];
00283 
00284       /* Set end position */
00285       ((proxyfsal_cookie_t *)end_position)->data = piter_entry->cookie;
00286 
00287       /* Get ready for next pdirent */
00288       cpt += 1;
00289 
00290       if(cpt >= nbreaddir)
00291         break;
00292     }
00293 
00294   /* The number of entries to be returned */
00295   *nb_entries = cpt;
00296 
00297   gsh_free(pxy_e4);
00298   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir);
00299 
00300 }
00301 
00315 fsal_status_t PROXYFSAL_closedir(fsal_dir_t * dir_descriptor       /* IN */
00316     )
00317 {
00318 
00319   /* sanity checks */
00320   if(!dir_descriptor)
00321     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir);
00322 
00323   ((proxyfsal_dir_t *)dir_descriptor)->pcontext = NULL;
00324 
00325   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_closedir);
00326 
00327 }