nfs-ganesha 1.4
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 #include <sys/types.h> 00005 #include <sys/stat.h> 00006 #include <fcntl.h> 00007 #include <unistd.h> 00008 #include <hpss_dirent.h> 00009 #include <u_signed64.h> 00010 #include <hpssclapiext.h> 00011 #include <hpss_api.h> 00012 #include <api_internal.h> 00013 00014 /* 00015 * Prototypes for static functions. 00016 */ 00017 00018 static int 00019 HPSSFSAL_Common_ReadAttrs(apithrdstate_t * ThreadContext, 00020 sec_cred_t * UserCred, 00021 ns_ObjHandle_t * ObjHandlePtr, 00022 unsigned32 ChaseOptions, 00023 #if HPSS_LEVEL >= 7322 00024 unsigned32 OptionFlags, 00025 #endif 00026 u_signed64 OffsetIn, 00027 unsigned32 BufferSize, 00028 unsigned32 GetAttributes, 00029 unsigned32 IgnInconstitMd, 00030 unsigned32 * End, 00031 u_signed64 * OffsetOut, ns_DirEntry_t * DirentPtr); 00032 00033 /*============================================================================ 00034 * 00035 * Function: HPSSFSAL_ReadRawAttrsHandle 00036 * 00037 * Synopsis: 00038 * 00039 * int 00040 * HPSSFSAL_ReadRawAttrsHandle( 00041 * ns_ObjHandle_t *ObjHandle, ** IN - directory object handle 00042 * u_signed64 OffsetIn, ** IN - directory position 00043 * sec_cred_t *Ucred, ** IN - user credentials 00044 * unsigned32 BufferSize, ** IN - size of output buffer 00045 * unsigned32 *End, ** OUT - hit end of directory 00046 * u_signed64 *OffsetOut, ** OUT - resulting directory position 00047 * ns_DirEntry_t *DirentPtr) ** OUT - directory entry information 00048 * 00049 * Description: 00050 * 00051 * The 'HPSSFSAL_ReadRawAttrsHandle' function fills in the passed buffer 00052 * with directory entries, include file/directory attributes, 00053 * beginning at the specified directory position. This routine 00054 * will NOT try to chase HPSS junctions encountered. 00055 * 00056 * Other Inputs: 00057 * None. 00058 * 00059 * Outputs: 00060 * DirentPtr: Directory entry. If null string is returned in 00061 * d_name and/or d_namelen == 0, we hit end of directory. 00062 * Return Value: 00063 * 0 - No error. 'DirentPtr' contains directory 00064 * information. 00065 * 00066 * Interfaces: 00067 * API_ClientAPIInit 00068 * API_ENTER 00069 * API_RETURN 00070 * HPSSFSAL_Common_ReadAttrs 00071 * 00072 * Resources Used: 00073 * 00074 * Limitations: 00075 * 00076 * Assumptions: 00077 * 00078 * Notes: 00079 * 00080 *-------------------------------------------------------------------------*/ 00081 00082 int HPSSFSAL_ReadRawAttrsHandle(ns_ObjHandle_t * ObjHandle, /* IN - directory object handle */ 00083 u_signed64 OffsetIn, /* IN - directory position */ 00084 sec_cred_t * Ucred, /* IN - user credentials */ 00085 unsigned32 BufferSize, /* IN - size of output buffer */ 00086 unsigned32 GetAttributes, /* IN - get object attributes? */ 00087 unsigned32 IgnInconstitMd, /* IN - ignore in case of inconstitent MD */ 00088 unsigned32 * End, /* OUT - hit end of directory */ 00089 u_signed64 * OffsetOut, /* OUT - resulting directory position */ 00090 ns_DirEntry_t * DirentPtr) /* OUT - directory entry information */ 00091 { 00092 volatile long error = 0; 00093 sec_cred_t *ucred_ptr; 00094 apithrdstate_t *threadcontext; 00095 static char function_name[] = "HPSSFSAL_ReadRawAttrsHandle"; 00096 00097 API_ENTER(function_name); 00098 00099 /* 00100 * Initialize the thread if not already initialized. 00101 * Get a pointer back to the thread specific context. 00102 */ 00103 00104 error = API_ClientAPIInit(&threadcontext); 00105 if(error != 0) 00106 { 00107 API_RETURN(error); 00108 } 00109 00110 /* 00111 * Make sure that we got a positive buffer size and a 00112 * valid object handle. 00113 */ 00114 00115 if(ObjHandle == NULL || BufferSize == 0) 00116 { 00117 API_RETURN(-EINVAL); 00118 } 00119 00120 /* 00121 * Make sure we got a non-NULL dirent pointer. 00122 */ 00123 00124 if((DirentPtr == NULL) || (End == NULL) || (OffsetOut == NULL)) 00125 { 00126 API_RETURN(-EFAULT); 00127 } 00128 00129 /* 00130 * If user credentials were not passed, use the ones in the 00131 * current thread context. 00132 */ 00133 00134 if(Ucred == (sec_cred_t *) NULL) 00135 ucred_ptr = &threadcontext->UserCred; 00136 else 00137 ucred_ptr = Ucred; 00138 00139 error = HPSSFSAL_Common_ReadAttrs(threadcontext, 00140 ucred_ptr, 00141 ObjHandle, 00142 API_CHASE_NONE, 00143 #if HPSS_LEVEL >= 7322 00144 NS_READDIR_FLAGS_NFS, 00145 #endif 00146 OffsetIn, 00147 BufferSize, 00148 GetAttributes, 00149 IgnInconstitMd, End, OffsetOut, DirentPtr); 00150 API_RETURN(error); 00151 } 00152 00153 /*============================================================================ 00154 * 00155 * Function: HPSSFSAL_Common_ReadAttrs 00156 * 00157 * Synopsis: 00158 * 00159 * static int 00160 * HPSSFSAL_Common_ReadAttrs( 00161 * apithrdstate_t *ThreadContext, ** IN - thread context 00162 * sec_cred_t *UserCred, ** IN - user credentials 00163 * ns_ObjHandle_t *ObjHandlePtr, ** IN - ID of object 00164 * unsigned32 ChaseOptions, ** IN - chase junctions ? 00165 * unsigned32 OptionFlags ** IN - readdir option flags 00166 * u_signed64 OffsetIn ** IN - starting directory offset 00167 * unsigned32 BufferSize ** IN - size of entry buffer 00168 * unsigned32 GetAttributes, ** IN - get object attributes? 00169 * unsigned32 *End ** OUT - hit end-of-directory? 00170 * u_signed64 *OffsetOut ** OUT - offset of next entry 00171 * ns_DirEntry_t *DirentPtr) ** OUT - returned entry info 00172 * 00173 * Description: 00174 * 00175 * The 'HPSSFSAL_Common_ReadAttrs' function performs the common processing 00176 * for the calls that return directory entry and entry attribute 00177 * information. 00178 * 00179 * Other Inputs: 00180 * None. 00181 * 00182 * Outputs: 00183 * < 0 - Error. 00184 * >= 0 - Number of entries returned. 00185 * 00186 * Interfaces: 00187 * API_AddAllRegisterValues 00188 * API_core_ReadDir 00189 * API_DEBUG_FPRINTF 00190 * API_GetUniqueRequestID 00191 * API_RemoveRegisterValues 00192 * API_TraversePath 00193 * cast64m 00194 * free 00195 * memset 00196 * sizeof 00197 * 00198 * Resources Used: 00199 * 00200 * Limitations: 00201 * 00202 * Assumptions: 00203 * 00204 * Notes: 00205 * 00206 *-------------------------------------------------------------------------*/ 00207 00208 static int 00209 HPSSFSAL_Common_ReadAttrs(apithrdstate_t * ThreadContext, 00210 sec_cred_t * UserCred, 00211 ns_ObjHandle_t * ObjHandle, 00212 unsigned32 ChaseOptions, 00213 #if HPSS_LEVEL >= 7322 00214 unsigned32 OptionFlags, 00215 #endif 00216 u_signed64 OffsetIn, 00217 unsigned32 BufferSize, 00218 unsigned32 GetAttributes, 00219 unsigned32 IgnInconstitMd, 00220 unsigned32 * End, 00221 u_signed64 * OffsetOut, ns_DirEntry_t * DirentPtr) 00222 { 00223 int cnt; 00224 ns_DirEntryConfArray_t direntbuf; 00225 ns_DirEntry_t *direntptr; 00226 long error = 0; 00227 char function_name[] = "HPSSFSAL_Common_ReadAttrs"; 00228 unsigned32 i; 00229 #if HPSS_LEVEL >= 622 00230 unsigned32 entry_cnt; 00231 #endif 00232 ns_DirEntry_t *outptr; 00233 hpss_reqid_t rqstid; 00234 u_signed64 select_flags; 00235 00236 #if HPSS_LEVEL >= 622 00237 /* figure out how many entries will fit in the clients buffer */ 00238 entry_cnt = BufferSize / sizeof(ns_DirEntry_t); 00239 #endif 00240 00241 direntbuf.DirEntry.DirEntry_len = 0; 00242 direntbuf.DirEntry.DirEntry_val = NULL; 00243 00244 if(GetAttributes == TRUE) 00245 { 00246 /* 00247 * Ask for all the attributes that are managed by the 00248 * Name Service. Start by setting all the bits in 00249 * the select flags, then clear the ones that are specific 00250 * to the Bitfile Service. 00251 */ 00252 00253 select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX); 00254 select_flags = API_RemoveRegisterValues(select_flags, 00255 #if HPSS_MAJOR_VERSION < 7 00256 CORE_ATTR_DM_DATA_STATE_FLAGS, 00257 CORE_ATTR_DONT_PURGE, 00258 #endif 00259 CORE_ATTR_REGISTER_BITMAP, 00260 CORE_ATTR_OPEN_COUNT, 00261 CORE_ATTR_READ_COUNT, 00262 CORE_ATTR_WRITE_COUNT, 00263 CORE_ATTR_TIME_LAST_WRITTEN, -1); 00264 } 00265 else 00266 select_flags = cast64m(0); 00267 00268 /* 00269 * Get a valid request Id and then read the directory entries. 00270 */ 00271 00272 rqstid = API_GetUniqueRequestID(); 00273 00274 error = API_core_ReadDir(ThreadContext, 00275 rqstid, 00276 UserCred, 00277 ObjHandle, 00278 #if HPSS_LEVEL >= 7322 00279 OptionFlags, 00280 #endif 00281 OffsetIn, 00282 #if HPSS_LEVEL < 732 00283 BufferSize, 00284 #else 00285 entry_cnt, 00286 #endif 00287 select_flags, End, &direntbuf); 00288 00289 /* In case of metadata inconsistency, it may return HPSS_ENOENT 00290 * when a directory entry has no associated entry in the FS... 00291 * In this case, we return null object attributes. 00292 */ 00293 if((error == HPSS_ENOENT) && IgnInconstitMd) 00294 { 00295 select_flags = cast64m(0); 00296 00297 rqstid = API_GetUniqueRequestID(); 00298 00299 error = API_core_ReadDir(ThreadContext, 00300 rqstid, 00301 UserCred, 00302 ObjHandle, 00303 #if HPSS_LEVEL >= 7322 00304 OptionFlags, 00305 #endif 00306 OffsetIn, BufferSize, select_flags, End, &direntbuf); 00307 } 00308 00309 if(error != 0) 00310 { 00311 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00312 "%s: Could not read directory entries.\n", function_name); 00313 } 00314 00315 if(error == 0) 00316 { 00317 00318 /* 00319 * Now load in the results from the call. 00320 */ 00321 00322 (void)memset(DirentPtr, 0, BufferSize); /* Todo Why does this crash the daemon ??*/ 00323 cnt = 0; 00324 00325 #if HPSS_LEVEL >= 622 00326 for(i = 0; i < direntbuf.DirEntry.DirEntry_len && i < entry_cnt; ++i) 00327 #else 00328 for(i = 0; i < direntbuf.DirEntry.DirEntry_len; ++i) 00329 #endif 00330 { 00331 direntptr = &(direntbuf.DirEntry.DirEntry_val[i]); 00332 outptr = &DirentPtr[cnt++]; 00333 00334 /* 00335 * If asked to chase junctions and this entry 00336 * is a junction, return the attributes for 00337 * the fileset/directory to which the junction 00338 * points. 00339 */ 00340 00341 if(((ChaseOptions & API_CHASE_JUNCTION) != 0) 00342 && direntptr->Attrs.Type == NS_OBJECT_TYPE_JUNCTION) 00343 { 00344 hpss_Attrs_t attrs; 00345 ns_ObjHandle_t obj_handle; 00346 u_signed64 select_flags; 00347 00348 memset(&obj_handle, 0, sizeof(obj_handle)); 00349 memset(&attrs, 0, sizeof(attrs)); 00350 select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX); 00351 00352 error = API_TraversePath(ThreadContext, 00353 rqstid, 00354 &ThreadContext->UserCred, 00355 ObjHandle, 00356 (char *)direntptr->Name, 00357 API_NULL_CWD_STACK, 00358 API_CHASE_JUNCTION, 00359 0, 00360 0, 00361 select_flags, 00362 cast64m(0), 00363 API_NULL_CWD_STACK, 00364 &obj_handle, &attrs, NULL, NULL, 00365 #if HPSS_MAJOR_VERSION < 7 00366 NULL, 00367 #endif 00368 NULL, NULL); 00369 00370 if(error != 0) 00371 { 00372 /* 00373 * If we can't find out what the junction points 00374 * to, log a message and return the attributes 00375 * of the junction itself. 00376 */ 00377 00378 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00379 "HPSSFSAL_Common_ReadAttrs: API_TraversePath" 00380 "failed, error = %d\n", error); 00381 error = 0; 00382 } 00383 else 00384 { 00385 /* 00386 * We got the fileset attributes, copy 00387 * them to the entry. 00388 */ 00389 00390 direntptr->ObjHandle = obj_handle; 00391 direntptr->Attrs = attrs; 00392 } 00393 } 00394 00395 *outptr = *direntptr; 00396 00397 } 00398 00399 if(error == 0) 00400 { 00401 if(direntbuf.DirEntry.DirEntry_len > 0) 00402 *OffsetOut = outptr->ObjOffset; 00403 else 00404 *OffsetOut = cast64m(0); 00405 00406 /* 00407 * Return the number of entries returned from the 00408 * core server. 00409 */ 00410 00411 error = cnt; 00412 } 00413 } 00414 00415 if(direntbuf.DirEntry.DirEntry_val != NULL) 00416 { 00417 free(direntbuf.DirEntry.DirEntry_val); 00418 } 00419 00420 return (error); 00421 }