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