nfs-ganesha 1.4
|
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 }