nfs-ganesha 1.4

api_rddir.c

Go to the documentation of this file.
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 }