nfs-ganesha 1.4

fsal_dirs.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=4:tabstop=4:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "fsal.h"
00019 #include "fsal_internal.h"
00020 #include "fsal_convert.h"
00021 #include <string.h>
00022 #include "abstract_mem.h"
00023 
00044 fsal_status_t LUSTREFSAL_opendir(fsal_handle_t * p_dir_handle,    /* IN */
00045                                  fsal_op_context_t * p_context,   /* IN */
00046                                  fsal_dir_t *dir_desc,   /* OUT */
00047                                  fsal_attrib_list_t * p_dir_attributes  /* [ IN/OUT ] */
00048     )
00049 {
00050   int rc;
00051   fsal_status_t status;
00052 
00053   fsal_path_t fsalpath;
00054   struct stat buffstat;
00055   lustrefsal_dir_t *p_dir_descriptor = (lustrefsal_dir_t *)dir_desc;
00056 
00057   /* sanity checks
00058    * note : dir_attributes is optionnal.
00059    */
00060   if(!p_dir_handle || !p_context || !p_dir_descriptor)
00061     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);
00062 
00063   /* get the path of the directory */
00064   status = fsal_internal_Handle2FidPath(p_context, p_dir_handle, &fsalpath);
00065   if(FSAL_IS_ERROR(status))
00066     ReturnStatus(status, INDEX_FSAL_opendir);
00067 
00068   /* get directory metadata */
00069   TakeTokenFSCall();
00070   rc = lstat(fsalpath.path, &buffstat);
00071   ReleaseTokenFSCall();
00072 
00073   if(rc != 0)
00074     {
00075       rc = errno;
00076       if(rc == ENOENT)
00077         Return(ERR_FSAL_STALE, rc, INDEX_FSAL_opendir);
00078       else
00079         Return(posix2fsal_error(rc), rc, INDEX_FSAL_opendir);
00080     }
00081 
00082   /* Test access rights for this directory */
00083   status = fsal_internal_testAccess(p_context, FSAL_R_OK, &buffstat, NULL);
00084   if(FSAL_IS_ERROR(status))
00085     ReturnStatus(status, INDEX_FSAL_opendir);
00086 
00087   /* if everything is OK, fills the dir_desc structure : */
00088 
00089   TakeTokenFSCall();
00090   p_dir_descriptor->p_dir = opendir(fsalpath.path);
00091   ReleaseTokenFSCall();
00092   if(!p_dir_descriptor->p_dir)
00093     Return(posix2fsal_error(errno), errno, INDEX_FSAL_opendir);
00094 
00095   memcpy(&(p_dir_descriptor->context), p_context, sizeof(lustrefsal_op_context_t));
00096   memcpy(&(p_dir_descriptor->path), &fsalpath, sizeof(fsal_path_t));
00097   memcpy(&(p_dir_descriptor->handle), p_dir_handle, sizeof(lustrefsal_handle_t));
00098 
00099   if(p_dir_attributes)
00100     {
00101       status = posix2fsal_attributes(&buffstat, p_dir_attributes);
00102       if(FSAL_IS_ERROR(status))
00103         {
00104           FSAL_CLEAR_MASK(p_dir_attributes->asked_attributes);
00105           FSAL_SET_MASK(p_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00106         }
00107     }
00108 
00109   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);
00110 
00111 }
00112 
00146 fsal_status_t LUSTREFSAL_readdir(fsal_dir_t *dir_desc,   /* IN */
00147                                  fsal_cookie_t start_pos,    /* IN */
00148                                  fsal_attrib_mask_t get_attr_mask,      /* IN */
00149                                  fsal_mdsize_t buffersize,      /* IN */
00150                                  fsal_dirent_t * p_pdirent,     /* OUT */
00151                                  fsal_cookie_t * p_end_position,  /* OUT */
00152                                  fsal_count_t * p_nb_entries,   /* OUT */
00153                                  fsal_boolean_t * p_end_of_dir  /* OUT */
00154     )
00155 {
00156   fsal_status_t st;
00157   fsal_count_t max_dir_entries;
00158   struct dirent *dp;
00159   struct dirent dpe;
00160   fsal_path_t fsalpath;
00161   int rc;
00162   lustrefsal_dir_t * p_dir_descriptor = (lustrefsal_dir_t *)dir_desc;
00163   lustrefsal_cookie_t start_position;
00164 
00165   /*****************/
00166   /* sanity checks */
00167   /*****************/
00168 
00169   if(!p_dir_descriptor || !p_pdirent || !p_end_position || !p_nb_entries || !p_end_of_dir)
00170     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
00171 
00172   max_dir_entries = (buffersize / sizeof(fsal_dirent_t));
00173   memcpy( (char *)& start_position.data.cookie, (char *)&start_pos.data, sizeof( off_t ) ) ;
00174 
00175   /***************************/
00176   /* seek into the directory */
00177   /***************************/
00178   errno = 0;
00179   if(start_position.data.cookie == 0)
00180     {
00181       rewinddir(p_dir_descriptor->p_dir);
00182       rc = errno;
00183     }
00184   else
00185     {
00186       seekdir(p_dir_descriptor->p_dir, start_position.data.cookie);
00187       rc = errno;
00188     }
00189 
00190   if(rc)
00191     Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir);
00192 
00193   /************************/
00194   /* browse the directory */
00195   /************************/
00196 
00197   *p_nb_entries = 0;
00198   while(*p_nb_entries < max_dir_entries)
00199     {
00200     /***********************/
00201       /* read the next entry */
00202     /***********************/
00203       TakeTokenFSCall();
00204       rc = readdir_r(p_dir_descriptor->p_dir, &dpe, &dp);
00205       ReleaseTokenFSCall();
00206       if(rc)
00207         {
00208           rc = errno;
00209           Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir);
00210         }
00211       /* End of directory */
00212       if(!dp)
00213         {
00214           *p_end_of_dir = 1;
00215           break;
00216         }
00217 
00218     /***********************************/
00219       /* Get information about the entry */
00220     /***********************************/
00221 
00222       /* skip . and .. */
00223       if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
00224         continue;
00225 
00226       /* build the full path of the file into "fsalpath */
00227       if(FSAL_IS_ERROR
00228          (st =
00229           FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &(p_pdirent[*p_nb_entries].name))))
00230         ReturnStatus(st, INDEX_FSAL_readdir);
00231 
00232       memcpy(&fsalpath, &(p_dir_descriptor->path), sizeof(fsal_path_t));
00233       st = fsal_internal_appendNameToPath(&fsalpath, &(p_pdirent[*p_nb_entries].name));
00234       if(FSAL_IS_ERROR(st))
00235         ReturnStatus(st, INDEX_FSAL_readdir);
00236 
00237       /* get object handle */
00238       TakeTokenFSCall();
00239       st = fsal_internal_Path2Handle((fsal_op_context_t *) &p_dir_descriptor->context, &fsalpath,
00240                                      &(p_pdirent[*p_nb_entries].handle));
00241       ReleaseTokenFSCall();
00242 
00243       if(FSAL_IS_ERROR(st))
00244         ReturnStatus(st, INDEX_FSAL_readdir);
00245 
00246     /************************
00247      * Fills the attributes *
00248      ************************/
00249       p_pdirent[*p_nb_entries].attributes.asked_attributes = get_attr_mask;
00250 
00251       st = LUSTREFSAL_getattrs(&(p_pdirent[*p_nb_entries].handle),
00252                                (fsal_op_context_t *) &p_dir_descriptor->context,
00253                                &p_pdirent[*p_nb_entries].attributes);
00254       if(FSAL_IS_ERROR(st))
00255         {
00256           FSAL_CLEAR_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes);
00257           FSAL_SET_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes,
00258                         FSAL_ATTR_RDATTR_ERR);
00259         }
00260 
00261       ((lustrefsal_cookie_t *) (&p_pdirent[*p_nb_entries].cookie))->data.cookie = telldir(p_dir_descriptor->p_dir);
00262       p_pdirent[*p_nb_entries].nextentry = NULL;
00263       if(*p_nb_entries)
00264         p_pdirent[*p_nb_entries - 1].nextentry = &(p_pdirent[*p_nb_entries]);
00265 
00266       memcpy((char *)p_end_position, (char *)&p_pdirent[*p_nb_entries].cookie,
00267              sizeof(lustrefsal_cookie_t));
00268       (*p_nb_entries)++;
00269     }
00270 
00271   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir);
00272 
00273 }
00274 
00286 fsal_status_t LUSTREFSAL_closedir(fsal_dir_t * p_dir_descriptor   /* IN */
00287     )
00288 {
00289 
00290   int rc;
00291 
00292   /* sanity checks */
00293   if(!p_dir_descriptor)
00294     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir);
00295 
00296 #ifdef _USE_POSIXDB_READDIR_BLOCK
00297   if(((lustrefsal_dir_t *)p_dir_descriptor)->p_dbentries)
00298     gsh_free(p_dir_descriptor->p_dbentries);
00299 #endif
00300 
00301   rc = closedir(((lustrefsal_dir_t *)p_dir_descriptor)->p_dir);
00302   if(rc != 0)
00303     Return(posix2fsal_error(errno), errno, INDEX_FSAL_closedir);
00304 
00305   /* fill dir_descriptor with zeros */
00306   memset(p_dir_descriptor, 0, sizeof(lustrefsal_dir_t));
00307 
00308   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_closedir);
00309 
00310 }