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