nfs-ganesha 1.4

api_open.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 <pthread.h>
00009 #include <sys/socket.h>
00010 #include <sys/select.h>
00011 #include <netdb.h>
00012 #include <netinet/in.h>
00013 #include <hpss_soid_func.h>
00014 #include <u_signed64.h>
00015 #include <pdata.h>
00016 #include <hpssclapiext.h>
00017 #include <api_internal.h>
00018 /*#include "dmg_types.h"*/
00019 #include <acct_av_lib.h>
00020 
00021 #ifdef LINUX
00022 #define pthread_mutexattr_default NULL
00023 #define pthread_condattr_default NULL
00024 #endif
00025 
00026 /*
00027  *  For determining if a returned access ticket is NULL.
00028  */
00029 
00030 TYPE_TOKEN_HPSS null_ticket;
00031 
00032 /*
00033  *  Prototypes for static routines.
00034  */
00035 
00036 static int HPSSFSAL_Common_Open(apithrdstate_t * ThreadContext, /* IN - thread context */
00037                                 hpss_reqid_t RequestID, /* IN - request id */
00038                                 ns_ObjHandle_t * ObjHandle,     /* IN - parent object handle */
00039                                 char *Path,     /* IN - file name */
00040                                 api_cwd_stack_t * CwdStack,     /* IN - cwd stack */
00041 #if HPSS_MAJOR_VERSION < 7
00042                                 int Oflag,      /* IN - open flags */
00043                                 mode_t Mode,    /* IN - create mode */
00044                                 TYPE_CRED_HPSS * Ucred, /* IN - user credentials */
00045 #else
00046                                 TYPE_CRED_HPSS * Ucred, /* IN - user credentials */
00047                                 int Oflag,      /* IN - open flags */
00048                                 mode_t Mode,    /* IN - create mode */
00049 #endif
00050                                 hpss_cos_hints_t * HintsIn,     /* IN - creation hints */
00051                                 hpss_cos_priorities_t * HintsPri,       /* IN - hint priorities */
00052                                 hpss_cos_hints_t * HintsOut,    /* OUT - actual hint values used */
00053                                 hpss_Attrs_t * AttrsOut,        /* OUT - returned attributes */
00054                                 ns_ObjHandle_t * HandleOut      /* OUT - returned handle */
00055 #if HPSS_MAJOR_VERSION < 7
00056                                 , TYPE_TOKEN_HPSS * AuthzTicket /* OUT - returned authorization */
00057 #elif HPSS_LEVEL >= 730
00058                                 , int LoopCount /* IN  - Recursion Counter */
00059 #endif
00060     );
00061 
00062 static int HPSSFSAL_Common_Create(apithrdstate_t * ThreadContext,       /* IN - thread context */
00063                                   hpss_reqid_t RequestID,       /* IN - request id */
00064                                   ns_ObjHandle_t * ObjHandle,   /* IN - parent object handle */
00065                                   char *Path,   /* IN - file name */
00066                                   api_cwd_stack_t * CwdStack,   /* IN - cwd stack */
00067                                   mode_t Mode,  /* IN - create mode */
00068                                   TYPE_CRED_HPSS * Ucred,       /* IN - user credentials */
00069                                   hpss_cos_hints_t * HintsIn,   /* IN - creation hints */
00070                                   hpss_cos_priorities_t * HintsPri,     /* IN - hint priorities */
00071 #if HPSS_MAJOR_VERSION < 7
00072                                   TYPE_TOKEN_HPSS * AuthzIn,    /* IN - authorization for bfs */
00073                                   unsigned32 CreateFlags,       /* IN - Bfs flags to set on create */
00074                                   ns_ObjHandle_t * ParentHandle,        /* IN - parent handle */
00075                                   hpss_Attrs_t * ParentAttrs,   /* IN - parent attributes */
00076                                   api_dmap_attrs_t * DMAttrsOut,        /* OUT - DMAP attributes */
00077                                   unsigned32 * FilesetCOS,      /* OUT - Fileset COS */
00078 #endif
00079                                   hpss_cos_hints_t * HintsOut,  /* OUT - actual hint values used */
00080                                   hpss_Attrs_t * AttrsOut,      /* OUT - returned attributes */
00081                                   ns_ObjHandle_t * HandleOut    /* OUT - returned handle */
00082 #if HPSS_MAJOR_VERSION < 7
00083                                   , TYPE_TOKEN_HPSS * AuthzOut  /* OUT - returned authorization */
00084 #endif
00085     );
00086 
00087 static int HPSSFSAL_Common_Open_Bitfile(apithrdstate_t * ThreadContext, /* IN - thread context */
00088                                         hpss_reqid_t RequestID, /* IN - request id */
00089                                         hpssoid_t * BitFileID,  /* IN - bitfile id */
00090                                         ns_ObjHandle_t * ObjHandlePtr,  /* IN - NS object handle */
00091                                         TYPE_CRED_HPSS * Ucred, /* IN - user credentials */
00092                                         int Oflag,      /* IN - open flags */
00093 #if HPSS_MAJOR_VERSION < 7
00094                                         TYPE_TOKEN_HPSS * AuthzTicket,  /* IN - client authorization */
00095                                         api_dmap_attrs_t * DMAttrs,     /* IN - DMAP attributes */
00096 #endif
00097                                         unsigned32 FilesetCOS,  /* IN - fileset containing file */
00098                                         filetable_t * FTPtr,    /* IN - file table pointer */
00099                                         int Fildes
00100 #if HPSS_MAJOR_VERSION >= 6
00101                                         , hpss_cos_hints_t * HintsOut   /* OUT - actual hint values used */
00102 #endif
00103 #if HPSS_LEVEL >= 622
00104                                         , u_signed64 * SegmentSize      /* OUT - current storage segment size */
00105 #endif
00106     );                          /* IN - file table index */
00107 
00108 #if HPSS_LEVEL >= 711
00109 static int HPSSFSAL_Common_Open_File(apithrdstate_t * ThreadContext,    /* IN - thread context */
00110                                      hpss_reqid_t RequestID,    /* IN - request id */
00111                                      ns_ObjHandle_t * ParentHandle,     /* IN - parent object handle */
00112                                      unsigned32 FilesetCOS,     /* IN - file set COS */
00113                                      char *Path,        /* IN - Path to file to be opened */
00114                                      sec_cred_t * Ucred,        /* IN - user credentials */
00115                                      acct_rec_t * ParentAcct,   /* IN - parent account code */
00116                                      int Oflag, /* IN - open flags */
00117                                      mode_t Mode,       /* IN - create mode */
00118                                      hpss_cos_hints_t * HintsIn,        /* IN - Desired class of service */
00119                                      hpss_cos_priorities_t * HintsPri,  /* IN - Priorities of hint struct */
00120                                      hpss_cos_hints_t * HintsOut,       /* OUT - Granted class of service */
00121                                      hpss_Attrs_t * AttrsOut,   /* OUT - returned attributes */
00122                                      ns_ObjHandle_t * HandleOut);
00123 
00124 static int HPSSFSAL_Common_Create_File(apithrdstate_t * ThreadContext,  /* IN - thread context */
00125                                        hpss_reqid_t RequestID,  /* IN - request id */
00126                                        ns_ObjHandle_t * ParentHandle,   /* IN - parent object handle */
00127                                        char *Path,      /* IN - Path to file to be opened */
00128                                        sec_cred_t * Ucred,      /* IN - user credentials */
00129                                        acct_rec_t * ParentAcct, /* IN - parent account code */
00130                                        mode_t Mode,     /* IN - create mode */
00131                                        hpss_cos_hints_t * HintsIn,      /* IN - Desired class of service */
00132                                        hpss_cos_priorities_t * HintsPri,        /* IN - Priorities of hint struct */
00133                                        hpss_cos_hints_t * HintsOut,     /* OUT - Granted class of service */
00134                                        hpss_Attrs_t * AttrsOut, /* OUT - returned attributes */
00135                                        ns_ObjHandle_t * HandleOut);
00136 
00137 #endif
00138 
00139 /*============================================================================
00140  *
00141  * Function:    HPSSFSAL_OpenHandle
00142  *
00143  * Synopsis:
00144  *
00145  * int
00146  * HPSSFSAL_OpenHandle(
00147  * ns_ObjHandle_t           *ObjHandle, ** IN - Parent object handle
00148  * char                     *Path,      ** IN - Path to file to be opened
00149  * int                      Oflag,      ** IN - Type of file access
00150  * mode_t                   Mode,       ** IN - Desired file perms if create
00151  * TYPE_CRED_HPSS           *Ucred,     ** IN - User credentials
00152  * hpss_cos_hints_t         *HintsIn,   ** IN - Desired class of service
00153  * hpss_cos_priorities_t    *HintsPri,  ** IN - Priorities of hint struct
00154  * hpss_cos_hints_t         *HintsOut,  ** OUT - Granted class of service
00155  * hpss_Attrs_t         *AttrsOut,      ** OUT - returned attributes
00156  * ns_ObjHandle_t               *HandleOut,     ** OUT - returned handle
00157  * TYPE_TOKEN_HPSS                  *AuthzTicket)** OUT - Client authorization
00158  *
00159  * Description:
00160  *
00161  *      The 'HPSSFSAL_OpenHandle' function establishes a connection between a file,
00162  *      specified by 'Path', taken relative to the directory indicated by
00163  *      'ObjHandle', and a file handle.
00164  *
00165  * Parameters:
00166  *
00167  * Outputs:
00168  *              non-negative -  opened file handle.
00169  *
00170  * Interfaces:
00171  *      DCE pthreads, DCE/RPC, HPSSFSAL_Common_Open.
00172  *
00173  * Resources Used:
00174  *
00175  * Limitations:
00176  *
00177  * Assumptions:
00178  *
00179  * Notes:
00180  *
00181  *-------------------------------------------------------------------------*/
00182 
00183 int HPSSFSAL_OpenHandle(ns_ObjHandle_t * ObjHandle,     /* IN - Parent object handle */
00184                         char *Path,     /* IN - Path to file to be opened */
00185                         int Oflag,      /* IN - Type of file access */
00186                         mode_t Mode,    /* IN - Desired file perms if create */
00187                         TYPE_CRED_HPSS * Ucred, /* IN - User credentials */
00188                         hpss_cos_hints_t * HintsIn,     /* IN - Desired class of service */
00189                         hpss_cos_priorities_t * HintsPri,       /* IN - Priorities of hint struct */
00190                         hpss_cos_hints_t * HintsOut,    /* OUT - Granted class of service */
00191                         hpss_Attrs_t * AttrsOut,        /* OUT - returned attributes */
00192                         ns_ObjHandle_t * HandleOut,     /* OUT - returned handle */
00193                         TYPE_TOKEN_HPSS * AuthzTicket)  /* OUT - Client authorization */
00194 {
00195   static char function_name[] = "HPSSFSAL_OpenHandle";
00196   long error = 0;               /* return error */
00197   hpss_reqid_t rqstid;          /* request id */
00198   TYPE_CRED_HPSS *ucred_ptr;    /* user credentials */
00199   apithrdstate_t *threadcontext;        /* thread context pointer */
00200 
00201   API_ENTER(function_name);
00202 
00203   /*
00204    *  Initialize the thread if not already initialized.
00205    *  Get a pointer back to the thread specific context.
00206    */
00207 
00208   error = API_ClientAPIInit(&threadcontext);
00209   if(error != 0)
00210     API_RETURN(error);
00211 
00212   /*
00213    *  Get a valid request id.
00214    */
00215 
00216   rqstid = API_GetUniqueRequestID();
00217 
00218   /*
00219    *  Check that the object handle is not NULL.
00220    */
00221 
00222   if(ObjHandle == (ns_ObjHandle_t *) NULL)
00223     API_RETURN(-EINVAL);
00224 
00225   /*
00226    *  Check that the pathname the string is not the NULL string.
00227    */
00228 
00229   if((Path != NULL) && (*Path == '\0'))
00230     API_RETURN(-ENOENT);
00231 
00232   /*
00233    * Make sure both pointers are NULL or both pointers are non-NULL
00234    */
00235 
00236   if((HintsIn == (hpss_cos_hints_t *) NULL &&
00237       HintsPri != (hpss_cos_priorities_t *) NULL)
00238      ||
00239      (HintsIn != (hpss_cos_hints_t *) NULL && HintsPri == (hpss_cos_priorities_t *) NULL))
00240     API_RETURN(-EINVAL);
00241 
00242   /*
00243    *  If user credentials were not passed, use the ones in the
00244    *  current thread context.
00245    */
00246 
00247   if(Ucred == (TYPE_CRED_HPSS *) NULL)
00248     ucred_ptr = &threadcontext->UserCred;
00249   else
00250     ucred_ptr = Ucred;
00251 
00252   /*
00253    *  Call HPSSFSAL_Common_Open() to perform the majority of the common open
00254    *  processing.
00255    */
00256 
00257   error = HPSSFSAL_Common_Open(threadcontext, rqstid, ObjHandle, Path, API_NULL_CWD_STACK,
00258 #if HPSS_MAJOR_VERSION < 7
00259                                Oflag, Mode, ucred_ptr,
00260 #else
00261                                ucred_ptr, Oflag, Mode,
00262 #endif
00263                                HintsIn, HintsPri, HintsOut, AttrsOut, HandleOut
00264 #if HPSS_MAJOR_VERSION < 7
00265                                , AuthzTicket
00266 #elif HPSS_LEVEL >= 730
00267                                , 0
00268 #endif
00269       );
00270 
00271   API_RETURN(error);
00272 }
00273 
00274 /*============================================================================
00275  *
00276  * Function:    HPSSFSAL_CreateHandle
00277  *
00278  * Synopsis:
00279  *
00280  * int
00281  * HPSSFSAL_CreateHandle(
00282  * ns_ObjHandle_t           *ObjHandle, ** IN - Parent object handle
00283  * char                     *Path,      ** IN - Path to file to be opened
00284  * mode_t                   Mode,       ** IN - Desired file perms if create
00285  * TYPE_CRED_HPSS           *Ucred,     ** IN - User credentials
00286  * hpss_cos_hints_t         *HintsIn,   ** IN - Desired class of service
00287  * hpss_cos_priorities_t    *HintsPri,  ** IN - Priorities of hint struct
00288  * hpss_cos_hints_t         *HintsOut,  ** OUT - Granted class of service
00289  * hpss_Attrs_t         *AttrsOut,      ** OUT - returned attributes 
00290  * ns_ObjHandle_t     *HandleOut,       ** OUT - returned handle 
00291  * TYPE_TOKEN_HPSS                  *AuthzTicket)** OUT - Client authorization
00292  *
00293  * Description:
00294  *
00295  *      The 'hpss_Create' function creates a file specified by
00296  *      by 'Path', with permissions as specified by 'Mode' and using
00297  *      the class of service values specified by 'HintsIn' and 'HintsPri',
00298  *      if non-NULL.
00299  *
00300  * Parameters:
00301  *
00302  *      ObjHandle       NS object handle of parent directory of Path.
00303  *
00304  *      Path            Names the file to be created.
00305  *
00306  *      Mode            Gives the file mode used for determining the
00307  *                      file mode for the created file.
00308  *
00309  *      HintsPri        Pointer to structure defining client preferences
00310  *                      for class of service.
00311  *
00312  *      HintsPri        Pointer to structure defining the priorities of
00313  *                      each COS structure field.
00314  *
00315  *      HintsPri        Pointer to structure defining COS with which
00316  *                      file was created.
00317  *
00318  * Outputs:
00319  *      Return value:
00320  *              Zero            - sucess.
00321  *              Non-zero        - error occurred.
00322  *
00323  * Interfaces:
00324  *      DCE pthreads, DCE/RPC, Common_Create.
00325  *
00326  * Resources Used:
00327  *
00328  * Limitations:
00329  *
00330  * Assumptions:
00331  *
00332  * Notes:
00333  *
00334  *-------------------------------------------------------------------------*/
00335 
00336 int HPSSFSAL_CreateHandle(ns_ObjHandle_t * ObjHandle,   /* IN - Parent object handle */
00337                           char *Path,   /* IN - Path to file to be created */
00338                           mode_t Mode,  /* IN - Desired file perms */
00339                           TYPE_CRED_HPSS * Ucred,       /* IN - User credentials */
00340                           hpss_cos_hints_t * HintsIn,   /* IN - Desired class of service */
00341                           hpss_cos_priorities_t * HintsPri,     /* IN - Priorities of hint struct */
00342                           hpss_cos_hints_t * HintsOut,  /* OUT - Granted class of service */
00343                           hpss_Attrs_t * AttrsOut,      /* OUT - returned attributes */
00344                           ns_ObjHandle_t * HandleOut,   /* OUT - returned handle */
00345                           TYPE_TOKEN_HPSS * AuthzTicket)        /* OUT - Client authorization */
00346 {
00347   static char function_name[] = "HPSSFSAL_CreateHandle";
00348   long error = 0;               /* return error */
00349   hpss_reqid_t rqstid;          /* request id */
00350   TYPE_TOKEN_HPSS ta;           /* authorization ticket */
00351   hpss_Attrs_t attr;            /* file attributes */
00352   hpss_Attrs_t parent_attr;     /* parent attributes */
00353   hpss_AttrBits_t select_flags; /* attribute selection flags */
00354   hpss_AttrBits_t parent_flags; /* attribute selection flags */
00355   ns_ObjHandle_t obj_handle;    /* file object handle */
00356   ns_ObjHandle_t parent_handle; /* file object handle */
00357   apithrdstate_t *threadcontext;        /* thread context pointer */
00358   TYPE_CRED_HPSS *ucred_ptr;    /* user credentials pointer */
00359   retry_cb_t retry_cb;          /* retry control block */
00360 
00361   API_ENTER(function_name);
00362 
00363   /*
00364    *  Initialize the thread if not already initialized.
00365    *  Get a pointer back to the thread specific context.
00366    */
00367 
00368   error = API_ClientAPIInit(&threadcontext);
00369   if(error != 0)
00370     API_RETURN(error);
00371 
00372   /*
00373    *  Get a valid request id.
00374    */
00375 
00376   rqstid = API_GetUniqueRequestID();
00377 
00378   /*
00379    *  Check that the object handle is not NULL.
00380    */
00381 
00382   if(ObjHandle == (ns_ObjHandle_t *) NULL)
00383     API_RETURN(-EINVAL);
00384 
00385   /*
00386    *  Check that there is a name for the new object
00387    */
00388 
00389   if(Path == NULL)
00390     API_RETURN(-EFAULT);
00391 
00392   if(*Path == '\0')
00393     API_RETURN(-ENOENT);
00394 
00395   /*
00396    * Make sure both pointers are NULL or both pointers are non-NULL
00397    */
00398 
00399   if((HintsIn == (hpss_cos_hints_t *) NULL &&
00400       HintsPri != (hpss_cos_priorities_t *) NULL)
00401      ||
00402      (HintsIn != (hpss_cos_hints_t *) NULL && HintsPri == (hpss_cos_priorities_t *) NULL))
00403     API_RETURN(-EINVAL);
00404 
00405   /*
00406    *  If user credentials were not passed, use the ones in the
00407    *  current thread context.
00408    */
00409 
00410   if(Ucred == (TYPE_CRED_HPSS *) NULL)
00411     ucred_ptr = &threadcontext->UserCred;
00412   else
00413     ucred_ptr = Ucred;
00414 
00415 #if HPSS_MAJOR_VERSION >= 7
00416   /*
00417    *  Call Common_Create() to perform the majority of the common open
00418    *  processing.
00419    */
00420 
00421   error = HPSSFSAL_Common_Create(threadcontext,
00422                                  rqstid,
00423                                  ObjHandle,
00424                                  Path,
00425                                  API_NULL_CWD_STACK,
00426                                  Mode,
00427                                  ucred_ptr,
00428                                  HintsIn, HintsPri, HintsOut, AttrsOut, HandleOut);
00429 
00430   if(error != 0)
00431     {
00432       API_DEBUG_FPRINTF(DebugFile, &rqstid,
00433                         "%s: Common_Create failed, error=%d\n", function_name, error);
00434     }
00435 
00436   /*
00437    * Gatekeeper retries have timed-out.
00438    */
00439 
00440   if(error == HPSS_ERETRY)
00441     error = -EAGAIN;
00442 
00443   API_RETURN(error);
00444 #else
00445 
00446   /*
00447    *  Need to see if the file already exists, and if not,
00448    *  get an access ticket.
00449    */
00450 
00451   (void)memset(&select_flags, 0, sizeof(select_flags));
00452   parent_flags = API_AddRegisterValues(cast64m(0),
00453                                        CORE_ATTR_ACCOUNT,
00454                                        CORE_ATTR_FILESET_ID,
00455                                        CORE_ATTR_FILESET_TYPE,
00456                                        CORE_ATTR_GATEWAY_UUID,
00457                                        CORE_ATTR_DM_HANDLE,
00458                                        CORE_ATTR_DM_HANDLE_LENGTH,
00459                                        CORE_ATTR_COS_ID, CORE_ATTR_FAMILY_ID, -1);
00460   (void)memset(&obj_handle, 0, sizeof(obj_handle));
00461   (void)memset(&attr, 0, sizeof(attr));
00462   (void)memset(&ta, 0, sizeof(ta));
00463 
00464   error = API_TraversePath(threadcontext,
00465                            rqstid,
00466                            ucred_ptr,
00467                            ObjHandle,
00468                            Path,
00469                            API_NULL_CWD_STACK,
00470                            API_CHASE_NONE,
00471                            0,
00472                            0,
00473                            select_flags,
00474                            parent_flags,
00475                            API_NULL_CWD_STACK,
00476                            &obj_handle,
00477                            &attr, &parent_handle, &parent_attr, &ta, NULL, NULL);
00478 
00479   if(error == 0)
00480     error = -EEXIST;
00481 
00482   /*
00483    *  If we got another error other than ENOENT or
00484    *  the returned ticket is zeroes (indicating
00485    *  that a component of the path prefix does
00486    *  not exist), we are done.
00487    */
00488 
00489   if((error != -ENOENT) || (memcmp(&ta, &null_ticket, sizeof(ta)) == 0))
00490     {
00491       API_DEBUG_FPRINTF(DebugFile, &rqstid,
00492                         "%s: Could not get attributes, error=%d\n", function_name, error);
00493     }
00494   else
00495     {
00496       /*
00497        *  Call Common_Create() to perform the majority of the common open
00498        *  processing.
00499        */
00500 
00501       error = HPSSFSAL_Common_Create(threadcontext,
00502                                      rqstid,
00503                                      ObjHandle,
00504                                      Path,
00505                                      API_NULL_CWD_STACK,
00506                                      Mode,
00507                                      ucred_ptr,
00508                                      HintsIn,
00509                                      HintsPri,
00510                                      &ta,
00511                                      0,
00512                                      &parent_handle,
00513                                      &parent_attr,
00514                                      NULL,
00515                                      NULL, HintsOut, AttrsOut, HandleOut, AuthzTicket);
00516 
00517       if(error != 0)
00518         {
00519           API_DEBUG_FPRINTF(DebugFile, &rqstid,
00520                             "%s: Common_Create failed, error=%d\n", function_name, error);
00521         }
00522     }
00523 
00524   /*
00525    * Gatekeeper retries have timed-out.
00526    */
00527 
00528   if(error == HPSS_ERETRY)
00529     error = -EAGAIN;
00530 
00531   API_RETURN(error);
00532 #endif                          /* version < 7 */
00533 }
00534 
00535 /*============================================================================
00536  *
00537  * Function:    HPSSFSAL_Common_Open
00538  *
00539  * Synopsis:
00540  *
00541  * static int
00542  * HPSSFSAL_Common_Open(
00543  * apithrdstate_t               *ThreadContext, ** IN - thread context
00544  * hpss_reqid_t                 RequestID,      ** IN - request id
00545  * ns_ObjHandle_t               *ObjHandle,     ** IN - parent object handle
00546  * char                         *Path,          ** IN - file name
00547  * api_cwd_stack_t              *CwdStack,      ** IN - cwd stack
00548  * int                          Oflag,          ** IN - open flags
00549  * mode_t                       Mode,           ** IN - create mode
00550  * TYPE_CRED_HPSS               *Ucred,         ** IN - user credentials
00551  * hpss_cos_hints_t             *HintsIn,       ** IN - creation hints
00552  * hpss_cos_priorities_t        *HintsPri,      ** IN - hint priorities
00553  * hpss_cos_hints_t             *HintsOut,      ** OUT - actual hint values
00554  * hpss_vattr_t                 *AttrsOut,      ** OUT - returned attributes
00555  * TYPE_TOKEN_HPSS                      *AuthzTicket)   ** OUT - returned authz
00556  *
00557  * Description:
00558  *
00559  *      The 'HPSSFSAL_Common_Open' function performs common processing for
00560  *      hpss_Open and HPSSFSAL_OpenHandle.
00561  *
00562  * Parameters:
00563  *
00564  * Outputs:
00565  *              non-negative -  opened file handle.
00566  *
00567  * Interfaces:
00568  *      DCE pthreads, DCE/RPC, API_core_GetAttrs, ns_Insert, 
00569  *      HPSSFSAL_Common_Open_Bitfile, API_ConvertPosixModeToMode,
00570  *      API_ConvertAttrsToVAttrs.
00571  *
00572  * Resources Used:
00573  *
00574  * Limitations:
00575  *
00576  * Assumptions:
00577  *
00578  * Notes:
00579  *
00580  *-------------------------------------------------------------------------*/
00581 
00582 #if HPSS_MAJOR_VERSION < 7
00583 
00584 static int HPSSFSAL_Common_Open(apithrdstate_t * ThreadContext, /* IN - thread context */
00585                                 hpss_reqid_t RequestID, /* IN - request id */
00586                                 ns_ObjHandle_t * ObjHandle,     /* IN - parent object handle */
00587                                 char *Path,     /* IN - file name */
00588                                 api_cwd_stack_t * CwdStack,     /* IN - cwd stack */
00589                                 int Oflag,      /* IN - open flags */
00590                                 mode_t Mode,    /* IN - create mode */
00591                                 TYPE_CRED_HPSS * Ucred, /* IN - user credentials */
00592                                 hpss_cos_hints_t * HintsIn,     /* IN - creation hints */
00593                                 hpss_cos_priorities_t * HintsPri,       /* IN - hint priorities */
00594                                 hpss_cos_hints_t * HintsOut,    /* OUT - actual hint values used */
00595                                 hpss_Attrs_t * AttrsOut,        /* OUT - returned attributes */
00596                                 ns_ObjHandle_t * HandleOut,     /* OUT - returned handle */
00597                                 TYPE_TOKEN_HPSS * AuthzTicket)  /* OUT - returned authorization */
00598 {
00599   static char function_name[] = "HPSSFSAL_Common_Open";
00600   int fildes;                   /* File descriptor */
00601   int checkflag;                /* Oflag check variable */
00602 #if HPSS_MAJOR_VERSION == 5
00603   volatile long error = 0;      /* return error */
00604 #else
00605   signed32 error = 0;           /* return error */
00606 #endif
00607   retry_cb_t retry_cb;          /* retry control block */
00608   hpss_Attrs_t attr;            /* file attributes */
00609   hpss_Attrs_t parent_attr;     /* parent attributes */
00610   hpss_AttrBits_t select_flags; /* attribute select bits */
00611   hpss_AttrBits_t parent_flags; /* parent attributes select bits */
00612   ns_ObjHandle_t obj_handle;    /* file handle */
00613   ns_ObjHandle_t parent_handle; /* parent handle */
00614   hpss_Attrs_t file_attrs;      /* attribute for created file */
00615   TYPE_TOKEN_HPSS ta, create_ta;        /* security tokens */
00616   filetable_t *ftptr;           /* file table entry pointer */
00617   api_dmap_attrs_t dmap_attrs;  /* DMAP attibutes for the file */
00618   int called_create = FALSE;    /* called common create */
00619   unsigned32 fileset_cos;       /* Fileset COS */
00620 
00621   /*
00622    *  Verify that the Oflag is valid.
00623    */
00624 
00625   checkflag = Oflag & O_ACCMODE;
00626   if((checkflag != O_RDONLY) && (checkflag != O_RDWR) && (checkflag != O_WRONLY))
00627     {
00628       return (-EINVAL);
00629     }
00630 
00631   /*
00632    *  Check that we do not have too many descriptors already open.
00633    */
00634 
00635   ftptr = ThreadContext->FileTable;
00636 
00637   API_LockMutex(&ftptr->Mutex);
00638 
00639   if(ftptr->NumOpenDesc >= _HPSS_OPEN_MAX)
00640     {
00641       error = -EMFILE;
00642     }
00643 
00644   if(error == 0)
00645     {
00646       /*
00647        *  Allocate a slot for the file to be opened.
00648        */
00649 
00650       for(fildes = 0; fildes < _HPSS_OPEN_MAX; fildes++)
00651         {
00652           if(ftptr->OpenDesc[fildes].Type == NO_OPEN_HANDLE)
00653             break;
00654         }
00655       if(fildes >= _HPSS_OPEN_MAX)
00656         {
00657           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00658                             "%s: Inconsistent descriptor table\n", function_name);
00659           kill(getpid(), SIGABRT);
00660         }
00661       ftptr->OpenDesc[fildes].Type = BFS_OPEN_HANDLE;
00662       ftptr->OpenDesc[fildes].Flags |= ENTRY_BUSY;
00663       ftptr->TotalOpens++;
00664       ftptr->NumOpenDesc++;
00665       ftptr->OpenDesc[fildes].descunion_u.OpenBF.DataDesc = -1;
00666     }
00667 
00668   API_UnlockMutex(&ftptr->Mutex);
00669 
00670   if(error != 0)
00671     return (error);
00672 
00673   /*
00674    * Store the global request id in the file table entry.
00675    */
00676 
00677   ftptr->OpenDesc[fildes].GlobalRqstId = RequestID;
00678 
00679   /*
00680    * If needed, retry the get attributes if the file is
00681    * created between the time we first get attributes and
00682    * the time we issue the create.
00683    */
00684 
00685   for(;;)
00686     {
00687 
00688       /*
00689        *  Get all the information about the entry at the given path.
00690        */
00691 
00692       (void)memset(&ta, 0, sizeof(ta));
00693       (void)memset(&attr, 0, sizeof(attr));
00694       (void)memset(&parent_attr, 0, sizeof(parent_attr));
00695       (void)memset(&file_attrs, 0, sizeof(file_attrs));
00696       (void)memset(&select_flags, 0, sizeof(select_flags));
00697       (void)memset(&parent_flags, 0, sizeof(parent_flags));
00698 
00699       /*
00700        * Get the COS for the parent directory
00701        */
00702 
00703       parent_flags = API_AddRegisterValues(cast64m(0),
00704                                            CORE_ATTR_ACCOUNT,
00705                                            CORE_ATTR_FILESET_ID,
00706                                            CORE_ATTR_FILESET_TYPE,
00707                                            CORE_ATTR_GATEWAY_UUID,
00708                                            CORE_ATTR_DM_HANDLE,
00709                                            CORE_ATTR_DM_HANDLE_LENGTH,
00710                                            CORE_ATTR_COS_ID, CORE_ATTR_FAMILY_ID, -1);
00711 
00712       /*
00713        *  If we are returning attributes, we need to get
00714        *  them all here.
00715        */
00716 
00717       if(AttrsOut == NULL)
00718         {
00719           select_flags = API_AddRegisterValues(cast64m(0),
00720                                                CORE_ATTR_BIT_FILE_ID,
00721                                                CORE_ATTR_TYPE,
00722                                                CORE_ATTR_FILESET_ID,
00723                                                CORE_ATTR_FILESET_TYPE,
00724                                                CORE_ATTR_GATEWAY_UUID,
00725                                                CORE_ATTR_DM_HANDLE,
00726                                                CORE_ATTR_DM_HANDLE_LENGTH, -1);
00727         }
00728       else
00729         select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX);
00730 
00731       error = API_TraversePath(ThreadContext,
00732                                RequestID,
00733                                Ucred,
00734                                ObjHandle,
00735                                Path,
00736                                CwdStack,
00737                                API_CHASE_NONE,
00738                                0,
00739                                0,
00740                                select_flags,
00741                                parent_flags,
00742                                API_NULL_CWD_STACK,
00743                                &obj_handle,
00744                                &attr, &parent_handle, &parent_attr, &ta, NULL, NULL);
00745 
00746       if((error != 0)
00747          && (error != -ENOENT || (memcmp(&ta, &null_ticket, sizeof(ta)) == 0)))
00748         {
00749           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00750                             "%s: Could not find entry.\n", function_name);
00751           break;                /* break out of retry loop */
00752         }
00753       else if(error == -ENOENT && (Oflag & O_CREAT) == 0)
00754         {
00755           /*
00756            *  No entry and we are not allowed to create a new one.
00757            */
00758 
00759           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00760                             "%s: Could not find entry (!O_CREATE).\n", function_name);
00761           break;                /* break out of retry loop */
00762         }
00763       else if((error == 0) && ((Oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)))
00764         {
00765           /*
00766            *  Can not create an already existing file.
00767            */
00768 
00769           error = -EEXIST;
00770           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00771                             "%s: File exists on a create exclusive.\n", function_name);
00772           break;                /* break out of retry loop */
00773         }
00774 
00775       /*
00776        *  If we get here then the file already exists or we are going to
00777        *  create a new one.
00778        */
00779 
00780       /*
00781        *  Check to make sure that we are not opening a directory.
00782        */
00783 
00784       if((error == 0)
00785          && (attr.Type != NS_OBJECT_TYPE_HARD_LINK) && (attr.Type != NS_OBJECT_TYPE_FILE))
00786         {
00787           error = -EISDIR;
00788           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00789                             "%s: Attempt to open a directory.\n", function_name);
00790           break;                /* break out of retry loop */
00791         }
00792 
00793       if((error == -ENOENT) && (Oflag & O_CREAT))
00794         {
00795 
00796 #if defined(API_DMAP_GATEWAY)
00797           /*
00798            * The gateway shouldn't be trying to create a
00799            * file through the open call, error out
00800            */
00801 
00802           error = -EINVAL;
00803           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00804                             "%s: Gateway attempting to create"
00805                             " a file via open.\n", function_name);
00806           break;                /* break out of retry loop */
00807 #else
00808 
00809           /*
00810            *  Call HPSSFSAL_Common_Create() to perform the majority of the
00811            *  common open processing.
00812            */
00813 
00814           Oflag &= (~O_TRUNC);  /* just creating, don't need to truncate */
00815           called_create = TRUE; /* set a flag to indicate file creation */
00816 
00817           create_ta = ta;
00818           memset(&dmap_attrs, 0, sizeof(api_dmap_attrs_t));
00819           error = HPSSFSAL_Common_Create(ThreadContext,
00820                                          RequestID,
00821                                          ObjHandle,
00822                                          Path,
00823                                          CwdStack,
00824                                          Mode,
00825                                          Ucred,
00826                                          HintsIn,
00827                                          HintsPri,
00828                                          &create_ta,
00829                                          0,
00830                                          &parent_handle,
00831                                          &parent_attr,
00832                                          &dmap_attrs,
00833                                          &fileset_cos,
00834                                          HintsOut, &file_attrs, &obj_handle, &ta);
00835 
00836           if(error != 0)
00837             {
00838               API_DEBUG_FPRINTF(DebugFile, &RequestID,
00839                                 "%s: Could not create file.\n", function_name);
00840             }
00841 #endif
00842         }
00843 
00844       /*
00845        * This file already exists
00846        */
00847 
00848       else if(error == 0)
00849         {
00850 
00851           file_attrs = attr;
00852           fileset_cos = parent_attr.COSId;
00853 
00854 #if ( (HPSS_MAJOR_VERSION == 5) && defined(API_DMAP_SUPPORT) ) \
00855     || ( (HPSS_MAJOR_VERSION == 6) && defined(API_DMAP_SUPPORT) && defined( API_MIRRORED_FILESETS ) )
00856 
00857           /*
00858            * If DMAPI support is enabled, then get the
00859            * fileset information and save the DMAP attributes
00860            */
00861 
00862           memset(&dmap_attrs, 0, sizeof(api_dmap_attrs_t));
00863           dmap_attrs.FilesetID = attr.FilesetId;
00864           dmap_attrs.FilesetType = attr.FilesetType;
00865           dmap_attrs.DMGuuid = attr.GatewayUUID;
00866           dmap_attrs.HandleLength = attr.DMHandleLength;
00867           memcpy(dmap_attrs.Handle, attr.DMHandle, dmap_attrs.HandleLength);
00868 
00869 #endif
00870 
00871         }
00872 
00873       /*
00874        * If the create failed because the file already
00875        * existed, just retry the loop, we should get the
00876        * file's attributes and not try creating again.
00877        * Otherwise, we are done with the create.
00878        */
00879 
00880       if((error == -EEXIST) && ((Oflag & O_EXCL) == 0))
00881         {
00882           /*
00883            * Reset the error status and retry count and
00884            * go back to the top of the loop.
00885            */
00886 
00887           error = 0;
00888         }
00889       else
00890         break;
00891 
00892     }                           /* end of create retry loop */
00893 
00894   /*
00895    *  If everything is OK to this point, try and open the file.
00896    */
00897 
00898   if(error == 0)
00899     {
00900       /*
00901        * Open the bitfile
00902        */
00903 
00904       error = HPSSFSAL_Common_Open_Bitfile(ThreadContext,
00905                                            RequestID,
00906                                            &file_attrs.BitfileId,
00907                                            &obj_handle,
00908                                            Ucred,
00909                                            Oflag,
00910                                            &ta, &dmap_attrs, fileset_cos, ftptr, fildes
00911 #if HPSS_MAJOR_VERSION == 6
00912                                            , HintsOut
00913 #endif
00914 #if HPSS_LEVEL >= 622
00915                                            , NULL
00916 #endif
00917           );
00918 
00919     }
00920 
00921   if(error != 0)
00922     {
00923       /*
00924        *  We had an open problem. Free up the allocated slot.
00925        */
00926 
00927       API_LockMutex(&ftptr->Mutex);
00928 
00929       ftptr->OpenDesc[fildes].Type = NO_OPEN_HANDLE;
00930       ftptr->OpenDesc[fildes].Flags = 0;
00931       ftptr->TotalOpens--;
00932       ftptr->NumOpenDesc--;
00933 
00934       API_UnlockMutex(&ftptr->Mutex);
00935 
00936       return (error);
00937     }
00938 
00939   /*
00940    *  Make sure 0 length files get invalidated on close, if necessary
00941    */
00942 
00943   if((called_create != FALSE) || (Oflag & O_TRUNC))
00944     {
00945       ftptr->OpenDesc[fildes].descunion_u.OpenBF.Updates++;
00946     }
00947 
00948   /*
00949    * If request return the security token and
00950    * the file attributes
00951    */
00952 
00953   if(AuthzTicket != (TYPE_TOKEN_HPSS *) NULL)
00954     *AuthzTicket = ta;
00955 
00956   if(AttrsOut != (hpss_Attrs_t *) NULL)
00957     *AttrsOut = file_attrs;
00958 
00959   if(HandleOut != (ns_ObjHandle_t *) NULL)
00960     *HandleOut = obj_handle;
00961 
00962   return (fildes);
00963 }
00964 
00965 #elif (HPSS_LEVEL == 710) || (HPSS_LEVEL == 711)
00966 static int HPSSFSAL_Common_Open(apithrdstate_t * ThreadContext, /* IN - thread context */
00967                                 hpss_reqid_t RequestID, /* IN - request id */
00968                                 ns_ObjHandle_t * ObjHandle,     /* IN - object handle */
00969                                 char *Path,     /* IN - Path to file to be opened */
00970                                 api_cwd_stack_t * CwdStack,     /* IN - cwd stack */
00971                                 sec_cred_t * Ucred,     /* IN - user credentials */
00972                                 int Oflag,      /* IN - open flags */
00973                                 mode_t Mode,    /* IN - create mode */
00974                                 hpss_cos_hints_t * HintsIn,     /* IN - Desired class of service */
00975                                 hpss_cos_priorities_t * HintsPri,       /* IN - Priorities of hint struct */
00976                                 hpss_cos_hints_t * HintsOut,    /* OUT - Granted class of service */
00977                                 hpss_Attrs_t * AttrsOut,        /* OUT - returned attributes */
00978                                 ns_ObjHandle_t * HandleOut)     /* OUT - returned handle */
00979 {
00980   static char function_name[] = "HPSSFSAL_Common_Open";
00981   volatile long error = 0;      /* return error */
00982   char *file;                   /* file name to create */
00983   char *parentpath;             /* path to file */
00984   ns_ObjHandle_t hndl;          /* parent handle */
00985   hpss_AttrBits_t attr_bits;    /* parent attributes bits */
00986   hpss_Attrs_t attrs;           /* parent attributes */
00987   ns_ObjHandle_t *hndl_ptr = ObjHandle; /* parent handle pointer */
00988   acct_rec_t *pacct_ptr = NULL; /* parent account pointer */
00989 
00990   /*
00991    * We want the last component of the supplied path.
00992    */
00993 
00994   file = (char *)malloc(HPSS_MAX_FILE_NAME);
00995   if(file == NULL)
00996     return (-ENOMEM);
00997 
00998   parentpath = (char *)malloc(HPSS_MAX_PATH_NAME);
00999   if(parentpath == NULL)
01000     {
01001       free(file);
01002       return (-ENOMEM);
01003     }
01004 
01005   /*
01006    * Divide the path into a path and object
01007    */
01008 
01009   if((error = API_DivideFilePath(Path, parentpath, file)) != 0)
01010     {
01011       free(file);
01012       free(parentpath);
01013       return (error);
01014     }
01015 
01016   /*
01017    * Get parent's COS ID -- we always need this so we set the
01018    * FilesetCOS correctly, which allows us to do changecos.
01019    */
01020 
01021   memset(&attrs, '\0', sizeof(attrs));
01022 
01023   if(API_PATH_NEEDS_TRAVERSAL(parentpath))
01024     {
01025       /*
01026        * If there is a path provided then, then lookup
01027        * the parent handle and account
01028        */
01029 
01030       attr_bits = API_AddRegisterValues(cast64m(0),
01031                                         CORE_ATTR_ACCOUNT,
01032                                         CORE_ATTR_TYPE, CORE_ATTR_COS_ID, -1);
01033       memset(&hndl, '\0', sizeof(hndl));
01034 
01035       error = API_TraversePath(ThreadContext,
01036                                RequestID,
01037                                Ucred,
01038                                ObjHandle,
01039                                parentpath,
01040                                CwdStack,
01041                                API_CHASE_ALL,
01042                                0,
01043                                0,
01044                                attr_bits,
01045                                cast64m(0),
01046                                API_NULL_CWD_STACK,
01047                                &hndl,
01048                                &attrs,
01049                                (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL);
01050       if(error == 0)
01051         {
01052           if(attrs.Type != NS_OBJECT_TYPE_DIRECTORY)
01053             error = -ENOTDIR;
01054           else
01055             {
01056               hndl_ptr = &hndl;
01057               pacct_ptr = &attrs.Account;
01058             }
01059         }
01060     }
01061   else if(API_PATH_IS_ROOT(parentpath))
01062     {
01063       /* If needed, use the root handle */
01064       error = API_InitRootHandle(ThreadContext, RequestID, &hndl_ptr);
01065     }
01066   else
01067     {
01068       /*
01069        * Otherwise , just look up the COS Id.
01070        */
01071       attr_bits = API_AddRegisterValues(cast64m(0), CORE_ATTR_COS_ID, -1);
01072 
01073       error = API_TraversePath(ThreadContext,
01074                                RequestID,
01075                                Ucred,
01076                                ObjHandle,
01077                                parentpath,
01078                                CwdStack,
01079                                API_CHASE_ALL,
01080                                0,
01081                                0,
01082                                attr_bits,
01083                                cast64m(0),
01084                                API_NULL_CWD_STACK,
01085                                &hndl,
01086                                &attrs,
01087                                (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL);
01088     }
01089 
01090   if(error == 0)
01091     {
01092       error = HPSSFSAL_Common_Open_File(ThreadContext,
01093                                         RequestID,
01094                                         hndl_ptr,
01095                                         attrs.COSId,
01096                                         file,
01097                                         Ucred,
01098                                         pacct_ptr,
01099                                         Oflag,
01100                                         Mode,
01101                                         HintsIn, HintsPri, HintsOut, AttrsOut, HandleOut);
01102     }
01103 
01104   free(file);
01105   free(parentpath);
01106 
01107   return (error);
01108 }
01109 
01110 #elif HPSS_LEVEL >= 730
01111 static int HPSSFSAL_Common_Open(apithrdstate_t * ThreadContext, /* IN - thread context */
01112                                 hpss_reqid_t RequestID, /* IN - request id */
01113                                 ns_ObjHandle_t * ObjHandle,     /* IN - object handle */
01114                                 char *Path,     /* IN - Path to file to be opened */
01115                                 api_cwd_stack_t * CwdStack,     /* IN - cwd stack */
01116                                 sec_cred_t * Ucred,     /* IN - user credentials */
01117                                 int Oflag,      /* IN - open flags */
01118                                 mode_t Mode,    /* IN - create mode */
01119                                 hpss_cos_hints_t * HintsIn,     /* IN - Desired class of service */
01120                                 hpss_cos_priorities_t * HintsPri,       /* IN - Priorities of hint struct */
01121                                 hpss_cos_hints_t * HintsOut,    /* OUT - Granted class of service */
01122                                 hpss_Attrs_t * AttrsOut,        /* OUT - returned attributes */
01123                                 ns_ObjHandle_t * HandleOut,     /* OUT - returned handle */
01124                                 int LoopCount)  /* IN  - Recursion Counter */
01125 {
01126   static char function_name[] = "Common_Open";
01127   volatile long error = 0;      /* return error */
01128   char *file;                   /* file name to create */
01129   char *parentpath;             /* path to file */
01130   ns_ObjHandle_t hndl;          /* parent handle */
01131   hpss_AttrBits_t attr_bits;    /* parent attributes bits */
01132   hpss_Attrs_t attrs;           /* parent attributes */
01133   ns_ObjHandle_t *hndl_ptr = ObjHandle; /* parent handle pointer */
01134   acct_rec_t *pacct_ptr = NULL; /* parent account pointer */
01135 
01136   /*
01137    * We want the last component of the supplied path.
01138    */
01139 
01140   file = (char *)malloc(HPSS_MAX_FILE_NAME);
01141   if(file == NULL)
01142     return (-ENOMEM);
01143 
01144   parentpath = (char *)malloc(HPSS_MAX_PATH_NAME);
01145   if(parentpath == NULL)
01146     {
01147       free(file);
01148       return (-ENOMEM);
01149     }
01150 
01151   /*
01152    * Divide the path into a path and object
01153    */
01154 
01155   if((error = API_DivideFilePath(Path, parentpath, file)) != 0)
01156     {
01157       free(file);
01158       free(parentpath);
01159       return (error);
01160     }
01161 
01162   /*
01163    * Get parent's COS ID -- we always need this so we set the
01164    * FilesetCOS correctly, which allows us to do changecos.
01165    */
01166 
01167   memset(&attrs, '\0', sizeof(attrs));
01168 
01169   if(API_PATH_NEEDS_TRAVERSAL(parentpath))
01170     {
01171       /*
01172        * If there is a path provided then, then lookup
01173        * the parent handle and account
01174        */
01175 
01176       attr_bits = API_AddRegisterValues(cast64m(0),
01177                                         CORE_ATTR_ACCOUNT,
01178                                         CORE_ATTR_TYPE, CORE_ATTR_COS_ID, -1);
01179       memset(&hndl, '\0', sizeof(hndl));
01180 
01181       error = API_TraversePath(ThreadContext,
01182                                RequestID,
01183                                Ucred,
01184                                ObjHandle,
01185                                parentpath,
01186                                CwdStack,
01187                                API_CHASE_ALL,
01188                                0,
01189                                0,
01190                                attr_bits,
01191                                cast64m(0),
01192                                API_NULL_CWD_STACK,
01193                                &hndl,
01194                                &attrs,
01195                                (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL);
01196       if(error == 0)
01197         {
01198           if(attrs.Type != NS_OBJECT_TYPE_DIRECTORY)
01199             error = -ENOTDIR;
01200           else
01201             {
01202               hndl_ptr = &hndl;
01203               pacct_ptr = &attrs.Account;
01204             }
01205         }
01206     }
01207   else if(API_PATH_IS_ROOT(parentpath))
01208     {
01209       /* If needed, use the root handle */
01210       error = API_InitRootHandle(ThreadContext, RequestID, &hndl_ptr);
01211     }
01212   else
01213     {
01214       /* Get the Fileset COS from the ThreadState */
01215       attrs.COSId = ThreadContext->CwdState.FilesetCOS;
01216     }
01217 
01218   if(error == 0)
01219     {
01220       error = HPSSFSAL_Common_Open_File(ThreadContext,
01221                                         RequestID,
01222                                         hndl_ptr,
01223                                         attrs.COSId,
01224                                         file,
01225                                         Ucred,
01226                                         pacct_ptr,
01227                                         Oflag,
01228                                         Mode,
01229                                         HintsIn, HintsPri, HintsOut, AttrsOut, HandleOut);
01230       if(error == HPSS_EISDIR)
01231         {
01232           /*
01233            * So we get this error back saying this was a directory.
01234            * That means that either 1) this file is a directory, or
01235            * 2) less obvious, this file is a symbolic link. Let's find out
01236            * which case we're in.
01237            */
01238           attr_bits = API_AddRegisterValues(cast64m(0), CORE_ATTR_TYPE, -1);
01239 
01240           error = API_core_GetAttrs(ThreadContext,
01241                                     RequestID,
01242                                     Ucred,
01243                                     hndl_ptr,
01244                                     file,
01245                                     CORE_GETATTRS_DONT_BACKUP,
01246                                     0,
01247                                     0,
01248                                     attr_bits,
01249                                     cast64m(0),
01250                                     NULL, &attrs, NULL, NULL, NULL, NULL, NULL);
01251 
01252           if(error != 0)
01253             {
01254               free(file);
01255               free(parentpath);
01256               return (-EISDIR);
01257             }
01258           if(attrs.Type == NS_OBJECT_TYPE_SYM_LINK)
01259             {
01260               char linkpath[HPSS_MAX_PATH_NAME];
01261 
01262               /*
01263                * Following symlinks here makes this recursive. To avoid 
01264                * symlink loops, we will restrict the number of tries to the
01265                * POSIX max number of symlinks which can be traversed during 
01266                * pathname resolution.
01267                */
01268               if(LoopCount >= HPSS_SYMLOOP_MAX)
01269                 {
01270                   API_DEBUG_FPRINTF(DebugFile, &RequestID,
01271                                     "Too many levels of symlinks."
01272                                     " path =%s, errno=%d\n", file, -ELOOP);
01273                   return (-ELOOP);
01274                 }
01275               /*
01276                * Read the link contents so we know what we should try to open
01277                * next.
01278                */
01279               error = hpss_ReadlinkHandle(hndl_ptr,
01280                                           file, linkpath, HPSS_MAX_PATH_NAME, Ucred);
01281 
01282               /*
01283                * ReadlinkHandle returns the number of
01284                * bytes in linkpath on success, so we just need error to be
01285                * positive.
01286                */
01287               if(error > 0)
01288                 {
01289                   /*
01290                    * Okay, so we tracked the symlink back to its humble
01291                    * file origins and now we're ready to try opening it again
01292                    * with the assurance that its not a symlink anymore.
01293                    * This time, its for real.
01294                     */
01295 
01296                    /*
01297                     * Note that we drop the CWD stack here because if this symlink
01298                     * took us back up the directory tree, but we'd still be using
01299                     * the old CwdStack, and so we'd end up going back up that stack
01300                     * instead of from whatever point we were at when we hit the
01301                     * symlink.
01302                     */
01303 
01304                   error = HPSSFSAL_Common_Open(ThreadContext,
01305                                                RequestID,
01306                                                hndl_ptr,
01307                                                linkpath,
01308 #if HPSS_LEVEL > 730
01309                                                API_NULL_CWD_STACK,
01310 #else
01311                                                CwdStack,
01312 #endif
01313                                                Ucred,
01314                                                Oflag,
01315                                                Mode,
01316                                                HintsIn,
01317                                                HintsPri,
01318                                                HintsOut,
01319                                                AttrsOut, HandleOut, ++LoopCount);
01320 
01321                 }               /* error from ReadlinkHandle > 0 */
01322               else
01323                 {
01324                   API_DEBUG_FPRINTF(DebugFile, &RequestID,
01325                                     "Could not get path for symlink."
01326                                     " path =%s, errno=%d\n", file, -error);
01327                 }
01328             }                   /* object is a sym link */
01329           else
01330             {
01331               error = -EISDIR;
01332             }
01333         }                       /* error == -EISDIR */
01334     }
01335 
01336   /* No error from traverse path */
01337   free(file);
01338   free(parentpath);
01339 
01340   return (error);
01341 }
01342 
01343 #endif
01344 
01345 /*============================================================================
01346  *
01347  * Function:    HPSSFSAL_Common_Create
01348  *
01349  * Synopsis:
01350  *
01351  * static int
01352  * HPSSFSAL_Common_Create(
01353  * apithrdstate_t               *ThreadContext, ** IN - thread context
01354  * unsigned32                   RequestID,      ** IN - request id
01355  * ns_ObjHandle_t               *ObjHandle,     ** IN - parent object handle
01356  * char                         *Path,          ** IN - file name
01357  * api_cwd_stack_t              *CwdStack,      ** IN - cwd stack
01358  * mode_t                       Mode,           ** IN - create mode
01359  * TYPE_CRED_HPSS               *Ucred,         ** IN - user credentials
01360  * hpss_cos_hints_t             *HintsIn,       ** IN - creation hints
01361  * hpss_cos_priorities_t        *HintsPri,      ** IN - hint priorities
01362  * TYPE_TOKEN_HPSS                      *AuthzIn,       ** IN - create authorization
01363  * unsigned32                   CreateFlags,    ** IN - bfs consistency flags
01364  * ns_ObjHandle_t               *ParentHandle,  ** IN - parent handle
01365  * hpss_Attrs_t                 *ParentAttrs,   ** IN - parent attributes
01366  * char                         *FileName,      ** IN - file name to create
01367  * api_dmap_attrs_t             *DMAttrsOut,    ** OUT - DMAP attributes
01368  * unsigned32                   *FilesetCOS,    ** OUT - Fileset COS
01369  * hpss_cos_hints_t             *HintsOut,      ** OUT - actual hint values
01370  * hpss_vattr_t                 *AttrsOut,      ** OUT - returned attributes
01371  * TYPE_TOKEN_HPSS                      *AuthzOut)      ** OUT - returned authz
01372  *
01373  * Description:
01374  *
01375  *      The 'Common_Create' function performs common processing for
01376  *      HPSSFSAL_Common_Open and hpss_Create.
01377  *
01378  * Parameters:
01379  *
01380  * Outputs:
01381  *              zero - create succeeded.
01382  *
01383  * Interfaces:
01384  *      DCE pthreads, DCE/RPC, API_TraversePath, API_core_CreateFile,
01385  *      API_ConvertPosixModeToMode, API_ConvertAttrsToVAttrs.
01386  *      API_DetermineAcct, av_cli_ValidateCreate, API_AddRegisterValues
01387  *
01388  * Resources Used:
01389  *
01390  * Limitations:
01391  *
01392  * Assumptions:
01393  *
01394  * Notes:
01395  *
01396  *-------------------------------------------------------------------------*/
01397 
01398 #if HPSS_MAJOR_VERSION < 7
01399 
01400 static int HPSSFSAL_Common_Create(apithrdstate_t * ThreadContext,       /* IN - thread context */
01401                                   hpss_reqid_t RequestID,       /* IN - request id */
01402                                   ns_ObjHandle_t * ObjHandle,   /* IN - parent object handle */
01403                                   char *Path,   /* IN - file name */
01404                                   api_cwd_stack_t * CwdStack,   /* IN - cwd stack */
01405                                   mode_t Mode,  /* IN - create mode */
01406                                   TYPE_CRED_HPSS * Ucred,       /* IN - user credentials */
01407                                   hpss_cos_hints_t * HintsIn,   /* IN - creation hints */
01408                                   hpss_cos_priorities_t * HintsPri,     /* IN - hint priorities */
01409                                   TYPE_TOKEN_HPSS * AuthzIn,    /* IN - create authorization */
01410                                   unsigned32 CreateFlags,       /* IN - bfs consistency flags */
01411                                   ns_ObjHandle_t * ParentHandle,        /* IN - parent handle */
01412                                   hpss_Attrs_t * ParentAttrs,   /* IN - parent attributes */
01413                                   api_dmap_attrs_t * DMAttrsOut,        /* OUT - DMAP attributes */
01414                                   unsigned32 * FilesetCOS,      /* OUT - Fileset COS */
01415                                   hpss_cos_hints_t * HintsOut,  /* OUT - actual hint values used */
01416                                   hpss_Attrs_t * AttrsOut,      /* OUT - returned attributes */
01417                                   ns_ObjHandle_t * HandleOut,   /* OUT - returned handle */
01418                                   TYPE_TOKEN_HPSS * AuthzOut)   /* OUT - returned authorization */
01419 {
01420   static char function_name[] = "HPSSFSAL_Common_Create";
01421   long error;                   /* return error */
01422   TYPE_TOKEN_HPSS ta;           /* security token */
01423   ns_ObjHandle_t obj_handle;    /* object handle */
01424   hpss_AttrBits_t select_flags; /* retrieve object attr bits */
01425   hpss_AttrBits_t update_flags; /* updated object attr bits */
01426   hpss_Attrs_t new_attr;        /* object attributes */
01427   hpss_Attrs_t attr_out;        /* returned object attributes */
01428   hpss_cos_md_t cos_info;       /* returned COS information */
01429   hpss_sclass_md_t sclass_info; /* returned level 0 sclass info */
01430   call_type_t call_type;        /* call HPSS or gateway */
01431   api_dmap_attrs_t dmap_attrs;  /* DMAP attributes */
01432   hpss_cos_hints_t hint, *hintptr;      /* overridden creation hints */
01433   hpss_cos_priorities_t prio, *prioptr; /* overridden hint priorities */
01434   retry_cb_t retry_cb;          /* retry control block */
01435   acct_rec_t cur_acct_code;     /* current site account code */
01436   acct_rec_t new_acct_code;     /* validated account code */
01437   TYPE_UUID_HPSS site_id;       /* site */
01438   ls_map_array_t *ls_map_array; /* Location map array */
01439   char *file;                   /* file name to create */
01440   char *newpath;                /* path to file */
01441 
01442   /*
01443    * We want the last component of the supplied path.
01444    */
01445 
01446   file = (char *)malloc(HPSS_MAX_FILE_NAME);
01447   if(file == NULL)
01448     return (-ENOMEM);
01449 
01450   newpath = (char *)malloc(HPSS_MAX_PATH_NAME);
01451   if(newpath == NULL)
01452     {
01453       free(file);
01454       free(newpath);
01455       return (-ENOMEM);
01456     }
01457 
01458   /*
01459    * Divide the path into a path and object
01460    */
01461 
01462   error = API_DivideFilePath(Path, newpath, file);
01463   free(newpath);
01464 
01465   if(error != 0)
01466     {
01467       free(file);
01468       return (-error);
01469     }
01470 
01471   /*
01472    *  Do account validation.
01473    */
01474 
01475   error = API_DetermineAcct(Ucred,
01476                             ThreadContext,
01477                             ParentHandle->CoreServerUUID,
01478                             RequestID, &site_id, &cur_acct_code);
01479   if(error != 0)
01480     {
01481       API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't"
01482                         " get the account code from the given"
01483                         " information: error= %d\n", function_name, error);
01484       free(file);
01485       return (error);
01486     }
01487 #if HPSS_MAJOR_VERSION == 5
01488   error = av_cli_ValidateCreate(site_id,
01489                                 RequestID,
01490                                 Ucred->DCECellId,
01491                                 Ucred->SecPWent.Uid,
01492                                 Ucred->SecPWent.Gid,
01493                                 cur_acct_code, ParentAttrs->Account, &new_acct_code);
01494 #elif HPSS_MAJOR_VERSION >= 6
01495   error = av_cli_ValidateCreate(site_id,
01496                                 RequestID,
01497                                 Ucred->RealmId,
01498                                 Ucred->Uid,
01499                                 Ucred->Gid,
01500                                 cur_acct_code, ParentAttrs->Account, &new_acct_code);
01501 #endif
01502   if(error != 0)
01503     {
01504       API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't validate"
01505                         " the account code: error= %d\n", function_name, error);
01506       free(file);
01507       return (error);
01508     }
01509 
01510   /*
01511    * Get the fileset id, type and gateway UUID from the parent
01512    */
01513 
01514   Ucred->CurAccount = new_acct_code;
01515   memset(&dmap_attrs, 0, sizeof(dmap_attrs));
01516   dmap_attrs.FilesetID = ParentAttrs->FilesetId;
01517   dmap_attrs.FilesetType = ParentAttrs->FilesetType;
01518   dmap_attrs.DMGuuid = ParentAttrs->GatewayUUID;
01519 
01520   /*
01521    * Call this function to determine which interface
01522    * to call (DMAP Gateway or the Core Server) depending
01523    * on if the object is DMAP mapped, which version of
01524    * the library this is, what type of DMAP file set
01525    * this is (sync or backup).
01526    */
01527 
01528 #if HPSS_MAJOR_VERSION == 5
01529   call_type = API_DetermineCall(dmap_attrs.FilesetType, &error);
01530 #elif HPSS_MAJOR_VERSION == 6
01531   call_type = API_DetermineCall(dmap_attrs.FilesetType, (signed32 *) & error);
01532 #endif
01533 
01534   if(call_type == API_CALL_DMG)
01535     {
01536       /*
01537        * Here we are being called by a non-gateway client and
01538        * trying to create a object in a DMAP file set.
01539        */
01540 
01541 #if ( (HPSS_MAJOR_VERSION == 5) && defined(API_DMAP_SUPPORT) && !defined(API_DMAP_GATEWAY) )\
01542      || ( (HPSS_MAJOR_VERSION == 6) && defined(API_DMAP_SUPPORT) && !defined(API_DMAP_GATEWAY)  && defined( API_MIRRORED_FILESETS ) )
01543 
01544       /*
01545        * The mode should have the regular file bit set and
01546        * the umask bits reset.
01547        */
01548 
01549       Mode |= S_IFREG;
01550       Mode &= ~(ThreadContext->Umask);
01551 
01552       /*
01553        * Call the DMAP Gateway to create the object on
01554        * HPSS and the DMAPI file system
01555        */
01556 
01557       error = API_dmg_Create(ThreadContext,
01558                              RequestID,
01559                              Ucred,
01560                              &ParentAttrs->GatewayUUID,
01561                              ParentAttrs->FilesetId,
01562                              ParentAttrs->DMHandle,
01563                              ParentAttrs->DMHandleLength,
01564                              file,
01565                              Mode,
01566                              NS_OBJECT_TYPE_FILE,
01567                              HintsIn,
01568                              HintsPri,
01569                              dmap_attrs.Handle, &dmap_attrs.HandleLength, HintsOut);
01570 
01571       if(error != 0)
01572         {
01573           API_DEBUG_FPRINTF(DebugFile, &RequestID,
01574                             "%s: API_dmg_Create failed:"
01575                             " error = %d\n", function_name, error);
01576           free(file);
01577           return (error);
01578         }
01579 
01580       /*
01581        * At this point the object should be created
01582        * so, if requested get the attributes and/or
01583        * a security token from the Core Server
01584        */
01585 
01586       if(AttrsOut != (hpss_Attrs_t *) NULL || AuthzOut != (TYPE_TOKEN_HPSS *) NULL)
01587         {
01588 
01589           select_flags = cast64m(0);
01590           (void)memset(&obj_handle, 0, sizeof(obj_handle));
01591           (void)memset(&attr_out, 0, sizeof(attr_out));
01592           (void)memset(&ta, 0, sizeof(ta));
01593 
01594           if(AttrsOut != (hpss_Attrs_t *) NULL)
01595             select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX);
01596 
01597           error = API_TraversePath(ThreadContext,
01598                                    RequestID,
01599                                    Ucred,
01600                                    ParentHandle,
01601                                    file,
01602                                    CwdStack,
01603                                    API_CHASE_NONE,
01604                                    0,
01605                                    0,
01606                                    select_flags,
01607                                    cast64m(0),
01608                                    API_NULL_CWD_STACK,
01609                                    &obj_handle, &attr_out, NULL, NULL, &ta, NULL, NULL);
01610 
01611           if(error != 0)
01612             {
01613               free(file);
01614               return (error);
01615             }
01616 
01617           /*
01618            * Return the requested security token
01619            */
01620 
01621           if(AuthzOut != (TYPE_TOKEN_HPSS *) NULL)
01622             (void)memcpy(AuthzOut, &ta, sizeof(*AuthzOut));
01623 
01624         }
01625 #endif
01626 
01627     }
01628   /* end  call_type == DMG */
01629   else if(call_type == API_CALL_HPSS)
01630     {
01631 
01632       /*
01633        * Here we are being call by either a gateway client
01634        * (creating a file on a DMAP file set) or a non-gateway
01635        * client trying to create a object in a non-DMAP
01636        * file set.
01637        */
01638 
01639       /*
01640        * If the COS for the fileset (where the file is to
01641        * be placed) is non-zero, redirect the file to the
01642        * COS specified by the fileset attributes.
01643        */
01644 
01645       if(ParentAttrs->COSId != 0)
01646         {
01647           /* Start with any hints & prios passed in */
01648           if(HintsIn != NULL)
01649             memcpy(&hint, HintsIn, sizeof(hint));
01650           else
01651             memset(&hint, 0, sizeof(hint));
01652           if(HintsPri != NULL)
01653             memcpy(&prio, HintsPri, sizeof(prio));
01654           else
01655             memset(&prio, 0, sizeof(prio));
01656 
01657           /* Select the COS based on that of the parent */
01658           hint.COSId = ParentAttrs->COSId;
01659           prio.COSIdPriority = REQUIRED_PRIORITY;
01660           hintptr = &hint;
01661           prioptr = &prio;
01662         }
01663       else
01664         {
01665           /*
01666            * Just use the Hints that were passed in.
01667            */
01668 
01669           hintptr = HintsIn;
01670           prioptr = HintsPri;
01671         }
01672 
01673       /*
01674        *  Create the file in HPSS.
01675        */
01676 
01677       (void)memset(&new_attr, 0, sizeof(new_attr));
01678       (void)memset(&attr_out, 0, sizeof(attr_out));
01679       if(AuthzOut != (TYPE_TOKEN_HPSS *) NULL)
01680         (void)memset(AuthzOut, 0, sizeof(*AuthzOut));
01681       (void)memset(&obj_handle, 0, sizeof(obj_handle));
01682 
01683       memset(&cos_info, 0, sizeof(cos_info));
01684       memset(&sclass_info, 0, sizeof(sclass_info));
01685       memset(&obj_handle, 0, sizeof(obj_handle));
01686 
01687       /*
01688        * Setup the input attributes.
01689        */
01690 
01691       API_ConvertPosixModeToMode(Mode & ~ThreadContext->Umask, &new_attr);
01692       new_attr.DataLength = cast64m(0);
01693       new_attr.Account = new_acct_code;
01694       new_attr.FamilyId = ParentAttrs->FamilyId;
01695       update_flags = API_AddRegisterValues(cast64m(0),
01696                                            CORE_ATTR_USER_PERMS,
01697                                            CORE_ATTR_GROUP_PERMS,
01698                                            CORE_ATTR_OTHER_PERMS,
01699                                            CORE_ATTR_SET_UID,
01700                                            CORE_ATTR_SET_GID,
01701                                            CORE_ATTR_SET_STICKY,
01702                                            CORE_ATTR_DATA_LENGTH,
01703                                            CORE_ATTR_ACCOUNT, CORE_ATTR_FAMILY_ID, -1);
01704 
01705 #if defined(API_DMAP_GATEWAY)
01706 
01707       /*
01708        * If the gateway asked us to set some consistency
01709        * bits, add'em before the call to create.
01710        */
01711 
01712       if(CreateFlags != 0)
01713         {
01714           new_attr.DMDataStateFlags = CreateFlags;
01715           update_flags = API_AddRegisterValues(update_flags,
01716                                                CORE_ATTR_DM_DATA_STATE_FLAGS, -1);
01717         }
01718 
01719       /*
01720        * If the gateway is trying to create a file on a
01721        * mirrored fileset, it must supply a UID & GID for
01722        * the file.
01723        */
01724 
01725       if(dmap_attrs.FilesetType == CORE_FS_TYPE_MIRRORED)
01726         {
01727           new_attr.UID = Ucred->SecPWent.Uid;
01728           new_attr.GID = Ucred->SecPWent.Gid;
01729 
01730           update_flags = API_AddRegisterValues(update_flags,
01731                                                CORE_ATTR_UID, CORE_ATTR_GID, -1);
01732         }
01733 #endif
01734 
01735       /*
01736        *  Only request returned attributes if we have somewhere to
01737        *  put them.
01738        */
01739 
01740       if(AttrsOut != (hpss_Attrs_t *) NULL)
01741         select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX);
01742       else
01743         select_flags = cast64m(0);
01744 
01745       error = API_core_CreateFile(ThreadContext,
01746                                   RequestID,
01747                                   Ucred,
01748                                   ParentHandle,
01749                                   file,
01750                                   hintptr,
01751                                   prioptr,
01752                                   update_flags,
01753                                   &new_attr,
01754                                   AuthzIn,
01755                                   select_flags,
01756                                   &attr_out,
01757                                   &obj_handle, &cos_info, &sclass_info, AuthzOut);
01758 
01759       if(error == 0 && (HintsOut != (hpss_cos_hints_t *) NULL))
01760         {
01761           /*
01762            *  The file now exists, go ahead and convert
01763            *  the returned hints, if requested.
01764            */
01765 
01766           HintsOut->COSId = cos_info.COSId;
01767           strncpy((char *)HintsOut->COSName, (char *)cos_info.COSName, HPSS_MAX_COS_NAME);
01768           HintsOut->OptimumAccessSize = cast64m(cos_info.OptimumAccessSize);
01769           HintsOut->MinFileSize = cos_info.MinFileSize;
01770           HintsOut->MaxFileSize = cos_info.MaxFileSize;
01771           HintsOut->AccessFrequency = cos_info.AccessFrequency;
01772           HintsOut->TransferRate = cos_info.TransferRate;
01773           HintsOut->AvgLatency = cos_info.AvgLatency;
01774           HintsOut->WriteOps = cos_info.WriteOps;
01775           HintsOut->ReadOps = cos_info.ReadOps;
01776           HintsOut->StageCode = cos_info.StageCode;
01777           HintsOut->StripeWidth = sclass_info.StripeWidth;
01778           HintsOut->StripeLength = sclass_info.StripeLength;
01779         }
01780 
01781     }
01782   /* end (if call_type == HPSS) */
01783   if(error == 0)
01784     {
01785       /*
01786        *  The file now exists, go ahead and convert
01787        *  the returned name server attributes.
01788        */
01789 
01790       if(AttrsOut != (hpss_Attrs_t *) NULL)
01791         {
01792           *AttrsOut = attr_out;
01793         }
01794 
01795       if(HandleOut != (ns_ObjHandle_t *) NULL)
01796         {
01797           *HandleOut = obj_handle;
01798         }
01799 
01800       /*
01801        * Return the COS of the parent
01802        */
01803 
01804       if(FilesetCOS != (unsigned32 *) NULL)
01805         *FilesetCOS = ParentAttrs->COSId;
01806 
01807       /*
01808        * If the DM attributes were requested, return them here.
01809        * The fileset id, fileset type and gateway UUID are
01810        * extracted from the parent's attributes. The DM handle
01811        * and handle length are returned from the gateway for
01812        * backup and mirror fileset accesses via a client, but
01813        * any creates coming from the gateway will not contain
01814        * a valid handle yet. This is because the handle can
01815        * only be determined after the file is created on the
01816        * DMAP side.
01817        */
01818 
01819       if(DMAttrsOut != (api_dmap_attrs_t *) NULL)
01820         {
01821           DMAttrsOut->FilesetID = dmap_attrs.FilesetID;
01822           DMAttrsOut->FilesetType = dmap_attrs.FilesetType;
01823           DMAttrsOut->DMGuuid = dmap_attrs.DMGuuid;
01824           DMAttrsOut->HandleLength = dmap_attrs.HandleLength;
01825           memcpy(DMAttrsOut->Handle, dmap_attrs.Handle, DMAttrsOut->HandleLength);
01826         }
01827     }
01828 
01829   free(file);
01830   return (error);
01831 }
01832 #else                           /* from version 7 */
01833 
01834 static int HPSSFSAL_Common_Create(apithrdstate_t * ThreadContext,       /* IN - thread context */
01835                                   hpss_reqid_t RequestID,       /* IN - request id */
01836                                   ns_ObjHandle_t * ObjHandle,   /* IN - parent object handle */
01837                                   char *Path,   /* IN - file name */
01838                                   api_cwd_stack_t * CwdStack,   /* IN - cwd stack */
01839                                   mode_t Mode,  /* IN - create mode */
01840                                   sec_cred_t * Ucred,   /* IN - user credentials */
01841                                   hpss_cos_hints_t * HintsIn,   /* IN - creation hints */
01842                                   hpss_cos_priorities_t * HintsPri,     /* IN - hint priorities */
01843                                   hpss_cos_hints_t * HintsOut,  /* OUT - actual hint values used */
01844                                   hpss_Attrs_t * AttrsOut,      /* OUT - returned attributes */
01845                                   ns_ObjHandle_t * HandleOut)   /* OUT - returned handle */
01846 {
01847   static char function_name[] = "HPSSFSAL_Common_Create";
01848   volatile long error = 0;      /* return error */
01849   char *file;                   /* file name to create */
01850   char *parentpath;             /* path to file */
01851   ns_ObjHandle_t hndl;          /* parent handle */
01852   ns_ObjHandle_t *hndl_ptr = ObjHandle; /* parent handle pointer */
01853   hpss_AttrBits_t attr_bits;    /* parent attributes bits */
01854   hpss_Attrs_t attrs;           /* parent attributes */
01855   acct_rec_t *pacct_ptr = NULL; /* parent account code pointer */
01856 
01857   /*
01858    * We want the last component of the supplied path.
01859    */
01860 
01861   file = (char *)malloc(HPSS_MAX_FILE_NAME);
01862   if(file == NULL)
01863     return (-ENOMEM);
01864 
01865   parentpath = (char *)malloc(HPSS_MAX_PATH_NAME);
01866   if(parentpath == NULL)
01867     {
01868       free(file);
01869       return (-ENOMEM);
01870     }
01871 
01872   /*
01873    * Divide the path into a path and object
01874    */
01875 
01876   if((error = API_DivideFilePath(Path, parentpath, file)) != 0)
01877     {
01878       free(file);
01879       free(parentpath);
01880       return (error);
01881     }
01882 
01883   /*
01884    * Traverse the path to the parent directory, if needed
01885    */
01886 
01887   if(API_PATH_NEEDS_TRAVERSAL(parentpath))
01888     {
01889 
01890       /*
01891        * If there is a path provided then, then lookup
01892        * the parent handle and account
01893        */
01894 
01895       attr_bits = API_AddRegisterValues(cast64m(0),
01896                                         CORE_ATTR_ACCOUNT,
01897                                         CORE_ATTR_TYPE, CORE_ATTR_COS_ID, -1);
01898 
01899       memset(&attrs, '\0', sizeof(attrs));
01900       memset(&hndl, '\0', sizeof(hndl));
01901 
01902       error = API_TraversePath(ThreadContext,
01903                                RequestID,
01904                                Ucred,
01905                                ObjHandle,
01906                                parentpath,
01907                                CwdStack,
01908                                API_CHASE_ALL,
01909                                0,
01910                                0,
01911                                attr_bits,
01912                                cast64m(0),
01913                                API_NULL_CWD_STACK,
01914                                &hndl,
01915                                &attrs,
01916                                (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL);
01917       if(error == 0)
01918         {
01919 
01920           if(attrs.Type != NS_OBJECT_TYPE_DIRECTORY)
01921             error = -ENOTDIR;
01922           else
01923             {
01924               hndl_ptr = &hndl;
01925               pacct_ptr = &attrs.Account;
01926             }
01927         }
01928     }
01929   else if(API_PATH_IS_ROOT(parentpath))
01930     {
01931       /* If needed, use the root handle */
01932       error = API_InitRootHandle(ThreadContext, RequestID, &hndl_ptr);
01933     }
01934 
01935   if(error == 0)
01936     {
01937       error = HPSSFSAL_Common_Create_File(ThreadContext,
01938                                           RequestID,
01939                                           hndl_ptr,
01940                                           file,
01941                                           Ucred,
01942                                           pacct_ptr,
01943                                           Mode,
01944                                           HintsIn,
01945                                           HintsPri, HintsOut, AttrsOut, HandleOut);
01946     }
01947 
01948   free(file);
01949   free(parentpath);
01950 
01951   return (error);
01952 
01953 }
01954 
01955 #endif
01956 
01957 /*============================================================================
01958  *
01959  * Function:    HPSSFSAL_Common_Open_Bitfile
01960  *
01961  * Synopsis:
01962  *
01963  * static int
01964  * HPSSFSAL_Common_Open_Bitfile(
01965  * apithrdstate_t       *ThreadContext, ** IN - thread context
01966  * hpss_reqid_t         RequestID,      ** IN - request id
01967  * hpssoid_t            *BitFileID,     ** IN - bitfile id
01968  * ns_ObjHandle_t       *ObjHandlePtr,  ** IN - NS object handle
01969  * int                  Oflag,          ** IN - open flags
01970  * TYPE_TOKEN_HPSS              *AuthzTicket,   ** IN - client authorization
01971  * api_dmap_attrs_t     *DMAttrs,       ** IN - DMAP attributes
01972  * unsigned32           FilesetCOS,     ** IN - fileset containing file
01973  * filetable_t          *FTPtr,         ** IN - file table pointer
01974  * int                  Fildes)         ** IN - file table index
01975  *
01976  * Description:
01977  *
01978  *      The 'HPSSFSAL_Common_Open_Bitfile' function performs common processing for
01979  *      hpss_OpenBitfile and Common_Open.
01980  *
01981  * Parameters:
01982  *
01983  * Outputs:
01984  *              0 - success.
01985  *
01986  * Interfaces:
01987  *      DCE pthreads, DCE/RPC, API_bfs_Open.
01988  *
01989  * Resources Used:
01990  *
01991  * Limitations:
01992  *
01993  * Assumptions:
01994  *
01995  * Notes:
01996  *   If this function returns an error, the calling function is
01997  *   responsible for freeing the allocated slot in the file table.
01998  *
01999  *-------------------------------------------------------------------------*/
02000 
02001 static int HPSSFSAL_Common_Open_Bitfile(apithrdstate_t * ThreadContext, /* IN - thread context */
02002                                         hpss_reqid_t RequestID, /* IN - request id */
02003                                         hpssoid_t * BitFileID,  /* IN - bitfile id */
02004                                         ns_ObjHandle_t * ObjHandlePtr,  /* IN - NS object handle */
02005                                         TYPE_CRED_HPSS * Ucred, /* IN - user credentials */
02006                                         int Oflag,      /* IN - open flags */
02007 #if HPSS_MAJOR_VERSION < 7
02008                                         TYPE_TOKEN_HPSS * AuthzTicket,  /* IN - client authorization */
02009                                         api_dmap_attrs_t * DMAttrs,     /* IN - DMAP attributes */
02010 #endif
02011                                         unsigned32 FilesetCOS,  /* IN - fileset containing file */
02012                                         filetable_t * FTPtr,    /* IN - file table pointer */
02013                                         int Fildes      /* IN - file table index */
02014 #if HPSS_MAJOR_VERSION >= 6
02015                                         , hpss_cos_hints_t * HintsOut   /* OUT - actual hint values used */
02016 #endif
02017 #if HPSS_LEVEL >= 622
02018                                         , u_signed64 * SegmentSize      /* OUT - current storage segment size */
02019 #endif
02020     )
02021 {
02022   static char function_name[] = "HPSSFSAL_Common_Open_Bitfile";
02023   long error = 0;               /* returned error */
02024   retry_cb_t retry_cb;          /* Retry control block */
02025   unsigned32 bfsopenflags;      /* open flags */
02026   hpss_object_handle_t bfhandle;        /* handle to open bitfile */
02027   bf_attrib_t bfattr;           /* attribute of open bitfile */
02028   TYPE_UUID_HPSS uuid;          /* BFS server UUID */
02029   openfiletable_t *open_ftptr;  /* open file table entry */
02030   open_bf_desc_t *open_bfdesc_ptr;      /* open bitfile descriptor */
02031 
02032 #if HPSS_MAJOR_VERSION >= 6
02033   hpss_cos_md_t cos_info,       /* COS metadata values */
02034   *cos_info_ptr = NULL;
02035   hpss_sclass_md_t sclass_info, /* SClass metadata values */
02036   *sclass_info_ptr = NULL;
02037 #endif
02038 
02039 #if ((HPSS_MAJOR_VERSION == 5) && defined (API_DMAP_SUPPORT)    && !defined(API_DMAP_GATEWAY))\
02040    ||( (HPSS_MAJOR_VERSION == 6) && defined (API_DMAP_SUPPORT)  && !defined(API_DMAP_GATEWAY) &&  defined ( API_MIRRORED_FILESETS ))
02041   dmg_object_attrs_t dmg_attr;  /* DMAP attributes */
02042   u_signed64 dmg_attr_bits;     /* DMAP attributes bits */
02043   u_signed64 current_size;      /* current size of the file */
02044 #endif
02045 
02046   /*
02047    * Get a pointer to the open file table
02048    * and the open bitfile descriptor.
02049    */
02050 
02051   open_ftptr = &FTPtr->OpenDesc[Fildes];
02052   open_bfdesc_ptr = &open_ftptr->descunion_u.OpenBF;
02053 
02054   /*
02055    * Translate the Oflag into BFS open flags.
02056    */
02057 
02058 #if HPSS_LEVEL >= 622
02059   if(Oflag & HPSS_O_STAGE_ASYNC && Oflag & HPSS_O_STAGE_BKGRD)
02060     {
02061       API_DEBUG_FPRINTF(DebugFile, &RequestID,
02062                         "%s: can't specify both STAGE_ASYNC & STAGE_BKGRD\n",
02063                         function_name);
02064       return (HPSS_EINVAL);
02065     }
02066 #endif
02067 
02068   if((Oflag & O_ACCMODE) == O_RDONLY)
02069     {
02070       bfsopenflags = BFS_OPEN_READ;
02071     }
02072   else if((Oflag & O_ACCMODE) == O_WRONLY)
02073     {
02074       bfsopenflags = BFS_OPEN_WRITE;
02075     }
02076   else
02077     {
02078       bfsopenflags = BFS_OPEN_READ | BFS_OPEN_WRITE;
02079     }
02080 
02081   if(Oflag & O_APPEND)
02082     bfsopenflags |= BFS_OPEN_APPEND;
02083   if(Oflag & O_TRUNC)
02084     bfsopenflags |= BFS_OPEN_TRUNCATE;
02085   if(Oflag & O_NONBLOCK)
02086     bfsopenflags |= BFS_OPEN_NO_STAGE;
02087 
02088 #if HPSS_LEVEL >= 622
02089   if(Oflag & HPSS_O_STAGE_ASYNC)
02090     {
02091       bfsopenflags |= (BFS_OPEN_STAGE_ASYNC);
02092       bfsopenflags &= ~(BFS_OPEN_NO_STAGE);
02093       if(Oflag & O_NONBLOCK)
02094         bfsopenflags |= BFS_OPEN_NDELAY;
02095     }
02096 
02097   if(Oflag & HPSS_O_STAGE_BKGRD)
02098     {
02099       bfsopenflags |= (BFS_OPEN_STAGE_BKGRD);
02100       bfsopenflags &= ~(BFS_OPEN_NO_STAGE);
02101       if(Oflag & O_NONBLOCK)
02102         bfsopenflags |= BFS_OPEN_NDELAY;
02103     }
02104 
02105   /*
02106    * if the file is being opened just to be truncated, don't bother
02107    * trying to stage it.
02108    */
02109   if(bfsopenflags & BFS_OPEN_TRUNCATE && bfsopenflags & BFS_OPEN_WRITE)
02110     {
02111       bfsopenflags &= ~(BFS_OPEN_STAGE_BKGRD | HPSS_O_STAGE_ASYNC);
02112       bfsopenflags |= BFS_OPEN_NO_STAGE;
02113     }
02114 #endif
02115 
02116 #if HPSS_LEVEL == 620
02117   /* have we already gotten hints data? */
02118   if(HintsOut != NULL && HintsOut->COSId == 0)
02119     {
02120       cos_info_ptr = &cos_info;
02121       sclass_info_ptr = &sclass_info;
02122     }
02123 #elif HPSS_LEVEL == 622
02124   /* have we already gotten hints data? */
02125   if((HintsOut != NULL && HintsOut->COSId == 0) || SegmentSize != NULL)
02126     {
02127       cos_info_ptr = &cos_info;
02128       sclass_info_ptr = &sclass_info;
02129     }
02130 #elif HPSS_MAJOR_VERSION == 7
02131   /* have we already gotten hints data? */
02132   if(HintsOut != NULL || SegmentSize != NULL)
02133     {
02134       cos_info_ptr = &cos_info;
02135       sclass_info_ptr = &sclass_info;
02136     }
02137 #endif
02138 
02139   /*
02140    * Get the Bitfile Server UUID from the bitfile SOID.
02141    */
02142 
02143   SOID_GetServerID(BitFileID, &uuid);
02144 
02145   /*
02146    *  Now try to issue an open the file in the BFS.
02147    */
02148 #if HPSS_MAJOR_VERSION == 5
02149   error = API_core_OpenFile(ThreadContext,
02150                             RequestID, BitFileID, *AuthzTicket, bfsopenflags, &bfhandle);
02151 #elif HPSS_MAJOR_VERSION == 6
02152   error = API_core_OpenFile(ThreadContext,
02153                             RequestID,
02154                             BitFileID,
02155                             *AuthzTicket,
02156                             bfsopenflags, cos_info_ptr, sclass_info_ptr, &bfhandle);
02157 #elif HPSS_MAJOR_VERSION == 7
02158   error = API_core_OpenBitfile(ThreadContext,
02159                                RequestID,
02160                                Ucred,
02161                                BitFileID,
02162                                bfsopenflags, cos_info_ptr, sclass_info_ptr, &bfhandle);
02163 #endif
02164 
02165 #if ((HPSS_MAJOR_VERSION == 5) && defined ( API_DMAP_SUPPORT ) && !defined (API_DMAP_GATEWAY )) \
02166     ||((HPSS_MAJOR_VERSION == 6) && defined ( API_DMAP_SUPPORT ) && !defined (API_DMAP_GATEWAY ) && defined ( API_MIRRORED_FILESETS ))
02167 
02168   if(error == HPSS_ENOTVALID)
02169     {
02170 
02171       /*
02172        * We are assuming that the client is trying to get all
02173        * the most valid data to the top level of the HPSS
02174        * hierarchy. The only way to make this possible is
02175        * to first make sure all the data in DMAP is backed
02176        * into HPSS properly (migrate) and then try to open
02177        * the file again. There should no need to stage data
02178        * on the second open because we will have just migrated
02179        * the valid data from the DMAP cache to the top level
02180        * in the HPSS hierarchy.
02181        */
02182 
02183       memset(&bfattr, 0, sizeof(bfattr));
02184 
02185       /*
02186        * Get the bitfile attributes because we need the 
02187        * the file size for the migrate
02188        */
02189 
02190       error = API_core_BitfileGetAttrs(ThreadContext,
02191                                        RequestID, BitFileID, *AuthzTicket, &bfattr);
02192 
02193       if(error != HPSS_E_NOERROR)
02194         {
02195           API_DEBUG_FPRINTF(DebugFile, &RequestID,
02196                             "%s: Couldn't get"
02197                             " bitfile attributes: %d\n", function_name, error);
02198         }
02199       else if(bfattr.BfAttribMd.Flags & CACHE_DATA_VALID)
02200         {
02201 
02202           /*
02203            * Migrate the data from DMAP
02204            */
02205 
02206           error = API_dmg_Migrate(ThreadContext,
02207                                   RequestID,
02208                                   &ThreadContext->UserCred,
02209                                   &DMAttrs->DMGuuid,
02210                                   DMAttrs->FilesetID,
02211                                   DMAttrs->Handle,
02212                                   DMAttrs->HandleLength,
02213                                   cast64m(0), bfattr.BfAttribMd.DataLen, 0);
02214 
02215         }
02216 
02217       if(error == HPSS_E_NOERROR)
02218         {
02219 
02220           /*
02221            * Try to open the file again, but this time there
02222            * should be no stage because we just updated the
02223            * data a the top of the hierarchy.
02224            */
02225 
02226           error = API_core_OpenFile(ThreadContext,
02227                                     RequestID,
02228                                     BitFileID, *AuthzTicket, bfsopenflags, &bfhandle);
02229 
02230           /*
02231            * If we were not able to migrate the cache
02232            * return a EBUSY to the user.
02233            */
02234 
02235           if(error == HPSS_ENOTVALID)
02236             {
02237               API_DEBUG_FPRINTF(DebugFile, &RequestID,
02238                                 "%s: Could not migrate: %d\n", function_name, error);
02239 
02240               error = -EBUSY;
02241             }
02242         }
02243     }
02244 #elif HPSS_MAJOR_VERSION < 7
02245   if(error == HPSS_ENOTVALID)
02246     {
02247       API_DEBUG_FPRINTF(DebugFile, &RequestID,
02248                         "%s: No dmap support compiled in\n", function_name);
02249       API_LogMsg(function_name, RequestID, CS_DEBUG,
02250                  COMMUNICATION_ERROR, WARNING, API_HPSS_DATA_NOT_VALID, errno);
02251       error = -EINVAL;
02252     }
02253 #endif
02254 
02255   if(error == 0)
02256     {
02257 
02258       /*
02259        *  We found an open table descriptor
02260        *  Fill in the descriptor with the open file state.
02261        */
02262 
02263       open_ftptr->Type = BFS_OPEN_HANDLE;
02264 
02265       open_bfdesc_ptr->FilesetCOS = FilesetCOS;
02266       if(ObjHandlePtr != (ns_ObjHandle_t *) NULL)
02267         open_ftptr->ObjectHandle = *ObjHandlePtr;
02268       open_bfdesc_ptr->BFHandle = bfhandle;
02269       open_bfdesc_ptr->Offset = cast64m(0);
02270       open_bfdesc_ptr->OpenFlag = Oflag;
02271       open_bfdesc_ptr->DataConnPtr = NULL;
02272 #if HPSS_MAJOR_VERSION < 7
02273       memset(&open_bfdesc_ptr->DMattrs, 0, sizeof(api_dmap_attrs_t));
02274       open_bfdesc_ptr->DMattrs.FilesetType = CORE_FS_TYPE_HPSS_ONLY;
02275 #endif
02276       open_bfdesc_ptr->CoreServerUUID = uuid;
02277       open_bfdesc_ptr->Updates = 0;
02278 #if HPSS_MAJOR_VERSION < 7
02279       pthread_mutex_init(&open_bfdesc_ptr->Mutex, pthread_mutexattr_default);
02280       pthread_cond_init(&open_bfdesc_ptr->Cond, pthread_condattr_default);
02281 #else
02282       open_bfdesc_ptr->Mutex = pthread_mutex_initializer;
02283       open_bfdesc_ptr->Cond = pthread_cond_initializer;
02284 #endif
02285 
02286 #if HPSS_MAJOR_VERSION < 7
02287       if(DMAttrs != NULL)
02288         {
02289           /*
02290            * Don't forget to save any DMAP information
02291            * in the open file descriptor entry
02292            */
02293 
02294           open_bfdesc_ptr->DMattrs = *DMAttrs;
02295         }
02296 #endif
02297 
02298       /*
02299        *  Get a socket and put out a listen for data transfers.
02300        */
02301 
02302       error = API_OpenListenDesc(API_TRANSFER_TCP,
02303                                  &open_bfdesc_ptr->ListenDesc,
02304                                  &open_bfdesc_ptr->ListenAddr_u);
02305 
02306       if(error != HPSS_E_NOERROR)
02307         {
02308           API_DEBUG_FPRINTF(DebugFile, &RequestID,
02309                             "Could not get listen socket." " errno =%d\n", -error);
02310 
02311           API_LogMsg(function_name, RequestID, CS_DEBUG,
02312                      COMMUNICATION_ERROR, WARNING, API_OPEN_LISTEN_DESC_ERROR, error);
02313 
02314         }
02315 #if defined(IPI3_SUPPORT)
02316 
02317       /*
02318        *  If we are doing IPI-3 transfers, then we need to open a
02319        *  data descriptor here.
02320        */
02321 
02322       if(API_TransferType == API_TRANSFER_IPI3)
02323         {
02324           error = API_OpenListenDesc(API_TRANSFER_IPI3,
02325                                      &open_bfdesc_ptr->DataDesc,
02326                                      &open_bfdesc_ptr->DataAddr_u);
02327 
02328           if(error != HPSS_E_NOERROR)
02329             {
02330               API_DEBUG_FPRINTF(DebugFile, &RequestID,
02331                                 "Could not get data port." " errno =%d\n", -error);
02332 
02333               API_LogMsg(function_name, RequestID, CS_DEBUG,
02334                          COMMUNICATION_ERROR, WARNING, API_OPEN_LISTEN_DESC_ERROR, error);
02335 
02336             }
02337         }
02338 #endif
02339 
02340       /*
02341        * Mark the file table entry as not busy.
02342        */
02343 
02344       API_LockMutex(&FTPtr->Mutex);
02345       open_ftptr->Flags = 0;
02346       API_UnlockMutex(&FTPtr->Mutex);
02347 
02348 #if HPSS_MAJOR_VERSION >= 6
02349       /*
02350        * If needed, build the return hints
02351        */
02352 
02353       if(HintsOut != NULL && HintsOut->COSId == 0)
02354         {
02355           HintsOut->COSId = cos_info.COSId;
02356           strncpy((char *)HintsOut->COSName, (char *)cos_info.COSName, HPSS_MAX_COS_NAME);
02357           HintsOut->Flags = cos_info.Flags;
02358           HintsOut->OptimumAccessSize = cast64m(cos_info.OptimumAccessSize);
02359           HintsOut->MinFileSize = cos_info.MinFileSize;
02360           HintsOut->MaxFileSize = cos_info.MaxFileSize;
02361           HintsOut->AccessFrequency = cos_info.AccessFrequency;
02362           HintsOut->TransferRate = cos_info.TransferRate;
02363           HintsOut->AvgLatency = cos_info.AvgLatency;
02364           HintsOut->WriteOps = cos_info.WriteOps;
02365           HintsOut->ReadOps = cos_info.ReadOps;
02366           HintsOut->StageCode = cos_info.StageCode;
02367           HintsOut->StripeWidth = sclass_info.StripeWidth;
02368           HintsOut->StripeLength = sclass_info.StripeLength;
02369         }
02370 #endif
02371 
02372 #if HPSS_LEVEL >= 622
02373       /*
02374        * If requested, return the storage segment size
02375        */
02376 
02377       if(SegmentSize != NULL)
02378         *SegmentSize = sclass_info.StorageSegmentSize;
02379 #endif
02380 
02381 #if (( HPSS_MAJOR_VERSION == 5) && defined (API_DMAP_SUPPORT) && !defined(API_DMAP_GATEWAY) )\
02382   || ((HPSS_MAJOR_VERSION == 6) && defined (API_DMAP_SUPPORT) && !defined(API_DMAP_GATEWAY) &&  defined ( API_MIRRORED_FILESETS ) )
02383       /*
02384        * If no errors and this file is not in a non-DMAP mannaged
02385        * area of the name space.
02386        */
02387 
02388       if(DMAttrs->FilesetType != CORE_FS_TYPE_HPSS_ONLY)
02389         {
02390 
02391           /*
02392            * If this file is in a DMAP mannaged area of the
02393            * name space and the truncate flag was set for
02394            * the open then, invalidate the file on the DMAP
02395            * side.
02396            */
02397 
02398           if(Oflag & O_TRUNC)
02399             {
02400 
02401               memset(&bfattr, 0, sizeof(bfattr));
02402 
02403               /*
02404                * Get the bitfile attributes because we need the 
02405                * file size for the invalidate
02406                */
02407 
02408               error = API_core_BitfileOpenGetAttrs(ThreadContext,
02409                                                    RequestID, open_bfdesc_ptr, &bfattr);
02410 
02411               if(error == HPSS_E_NOERROR)
02412                 {
02413                   memset(&dmg_attr, 0, sizeof(dmg_object_attrs_t));
02414                   memset(&dmg_attr_bits, 0, sizeof(u_signed64));
02415 
02416                   /*
02417                    * File size should be zero
02418                    */
02419 
02420                   dmg_attr_bits = cast64m(CHANGE_FILESIZE);
02421                   dmg_attr.Type = NS_OBJECT_TYPE_FILE;
02422                   dmg_attr.Attrs.Attrs.DataLength = bld64m(0, 0);
02423 
02424                   error = API_dmg_InvalidateCache(ThreadContext,
02425                                                   RequestID,
02426                                                   Ucred,
02427                                                   &DMAttrs->DMGuuid,
02428                                                   DMAttrs->FilesetID,
02429                                                   DMAttrs->Handle,
02430                                                   DMAttrs->HandleLength,
02431                                                   cast64m(0),
02432                                                   bfattr.BfAttribMd.DataLen,
02433                                                   0, dmg_attr_bits, &dmg_attr);
02434 
02435                 }
02436             }
02437         }
02438 #endif
02439 
02440     }
02441 
02442   return (error);
02443 }
02444 
02445 #if HPSS_LEVEL >= 711
02446 static int HPSSFSAL_Common_Open_File(apithrdstate_t * ThreadContext,    /* IN - thread context */
02447                                      hpss_reqid_t RequestID,    /* IN - request id */
02448                                      ns_ObjHandle_t * ParentHandle,     /* IN - parent object handle */
02449                                      unsigned32 FilesetCOS,     /* IN - file set COS */
02450                                      char *Path,        /* IN - Path to file to be opened */
02451                                      sec_cred_t * Ucred,        /* IN - user credentials */
02452                                      acct_rec_t * ParentAcct,   /* IN - parent account code */
02453                                      int Oflag, /* IN - open flags */
02454                                      mode_t Mode,       /* IN - create mode */
02455                                      hpss_cos_hints_t * HintsIn,        /* IN - Desired class of service */
02456                                      hpss_cos_priorities_t * HintsPri,  /* IN - Priorities of hint struct */
02457                                      hpss_cos_hints_t * HintsOut,       /* OUT - Granted class of service */
02458                                      hpss_Attrs_t * AttrsOut,   /* OUT - returned attributes */
02459                                      ns_ObjHandle_t * HandleOut)
02460 {
02461   static char function_name[] = "Common_Open_File";
02462   volatile long error = 0;      /* return error */
02463   filetable_t *ftptr;           /* file table pointer */
02464   int fildes;                   /* File descriptor */
02465   int checkflag;                /* check for valid file access */
02466   unsigned32 oflags;            /* open flags */
02467   hpss_object_handle_t bfhandle;        /* new open bitfile handle */
02468   ns_ObjHandle_t objhandle;     /* new bitfile object handle  */
02469   hpss_AttrBits_t new_attr_bits;        /* new bitfile attr bits */
02470   hpss_Attrs_t new_attrs;       /* new bitfile attributes */
02471   openfiletable_t *open_ftptr;  /* open file table entry */
02472   open_bf_desc_t *open_bfdesc_ptr;      /* open bitfile descriptor */
02473   hpss_cos_md_t cosinfo;        /* returned cos info */
02474   hpss_sclass_md_t sclassinfo;  /* returned storage class info */
02475   hpss_AttrBits_t ret_attr_bits;        /* return attr bits */
02476   hpss_Attrs_t ret_attrs;       /* return attributes */
02477   acct_rec_t pacct;             /* parent account */
02478 
02479   API_ENTER(function_name);
02480 
02481   /*
02482    *  Verify that the Oflag is valid.
02483    */
02484 
02485   checkflag = Oflag & O_ACCMODE;
02486   if((checkflag != O_RDONLY) && (checkflag != O_RDWR) && (checkflag != O_WRONLY))
02487     {
02488       return (-EINVAL);
02489     }
02490 
02491   /*
02492    * Translate the Oflag into BFS open flags.
02493    */
02494 
02495   if((Oflag & O_ACCMODE) == O_RDONLY)
02496     {
02497       oflags = BFS_OPEN_READ;
02498     }
02499   else if((Oflag & O_ACCMODE) == O_WRONLY)
02500     {
02501       oflags = BFS_OPEN_WRITE;
02502     }
02503   else
02504     {
02505       oflags = BFS_OPEN_READ | BFS_OPEN_WRITE;
02506     }
02507 
02508   if(Oflag & O_APPEND)
02509     oflags |= BFS_OPEN_APPEND;
02510   if(Oflag & O_TRUNC)
02511     oflags |= BFS_OPEN_TRUNCATE;
02512   if(Oflag & O_NONBLOCK)
02513     oflags |= BFS_OPEN_NO_STAGE;
02514   if(Oflag & O_CREAT)
02515     oflags |= BFS_OPEN_CREAT;
02516   if(Oflag & O_EXCL)
02517     oflags |= BFS_OPEN_EXCL;
02518 
02519   /*
02520    *  Check that we do not have too many descriptors already open.
02521    */
02522 
02523   ftptr = ThreadContext->FileTable;
02524 
02525   API_LockMutex(&ftptr->Mutex);
02526 
02527   if(ftptr->NumOpenDesc >= _HPSS_OPEN_MAX)
02528     {
02529       error = -EMFILE;
02530     }
02531 
02532   if(error == 0)
02533     {
02534       /*
02535        *  Allocate a slot for the file to be opened.
02536        */
02537 
02538       for(fildes = 0; fildes < _HPSS_OPEN_MAX; fildes++)
02539         {
02540           if(ftptr->OpenDesc[fildes].Type == NO_OPEN_HANDLE)
02541             break;
02542         }
02543       if(fildes >= _HPSS_OPEN_MAX)
02544         {
02545           API_DEBUG_FPRINTF(DebugFile, &RequestID,
02546                             "%s: Inconsistent descriptor table\n", function_name);
02547           kill(getpid(), SIGABRT);
02548         }
02549       ftptr->OpenDesc[fildes].Type = BFS_OPEN_HANDLE;
02550       ftptr->OpenDesc[fildes].Flags |= ENTRY_BUSY;
02551       ftptr->TotalOpens++;
02552       ftptr->NumOpenDesc++;
02553       ftptr->OpenDesc[fildes].descunion_u.OpenBF.DataDesc = -1;
02554       open_ftptr = &ftptr->OpenDesc[fildes];
02555       open_bfdesc_ptr = &open_ftptr->descunion_u.OpenBF;
02556     }
02557 
02558   API_UnlockMutex(&ftptr->Mutex);
02559 
02560   if(error != 0)
02561     {
02562       return (error);
02563     }
02564 
02565   /* Initialize input to the open */
02566 
02567   memset(&new_attrs, '\0', sizeof(new_attrs));
02568   new_attr_bits = ret_attr_bits = cast64m(0);
02569 
02570   /*
02571    * Are we trying to create this file?
02572    */
02573 
02574   if(oflags & BFS_OPEN_CREAT)
02575     {
02576       acct_rec_t cur_acct_code; /* current site account code */
02577       acct_rec_t new_acct_code; /* validated account code */
02578       hpss_uuid_t site_id;      /* site */
02579 
02580       /*
02581        *  Do account validation.
02582        */
02583 
02584       if((error = API_DetermineAcct(Ucred,
02585                                     ThreadContext,
02586                                     ParentHandle->CoreServerUUID,
02587                                     RequestID, &site_id, &cur_acct_code)) != 0)
02588         {
02589           API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't"
02590                             " get the account code from the given"
02591                             " information: error= %d\n", function_name, error);
02592         }
02593       else
02594         {
02595           if(ParentAcct == NULL)
02596             {
02597               ParentAcct = &pacct;
02598               if((error = API_GetAcctForParent(ThreadContext,
02599                                                RequestID, ParentHandle, &pacct)) != 0)
02600                 {
02601                   API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't"
02602                                     " get the account id for the given"
02603                                     " parent handle: error= %d\n", function_name, error);
02604                 }
02605             }
02606 
02607           if(error == 0)
02608             {
02609               if((error = av_cli_ValidateCreate(site_id,
02610                                                 RequestID,
02611                                                 Ucred->RealmId,
02612                                                 Ucred->Uid,
02613                                                 Ucred->Gid,
02614                                                 cur_acct_code,
02615                                                 *ParentAcct, &new_acct_code)) != 0)
02616                 {
02617                   API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't validate"
02618                                     " the account code: error= %d\n",
02619                                     function_name, error);
02620                   error = -EPERM;
02621                 }
02622               else
02623                 {
02624                   /*
02625                    * Everything went okay, setup the attributes for the new file
02626                    */
02627                   API_ConvertPosixModeToMode(Mode & ~ThreadContext->Umask, &new_attrs);
02628                   Ucred->CurAccount = new_attrs.Account = new_acct_code;
02629 
02630                   new_attr_bits = API_AddRegisterValues(cast64m(0),
02631                                                         CORE_ATTR_USER_PERMS,
02632                                                         CORE_ATTR_GROUP_PERMS,
02633                                                         CORE_ATTR_OTHER_PERMS,
02634                                                         CORE_ATTR_MODE_PERMS,
02635                                                         CORE_ATTR_ACCOUNT, -1);
02636 
02637                 }
02638             }
02639         }
02640     }
02641 
02642   /*
02643    * If everything went okay, open/create the file
02644    */
02645 
02646   if(error == 0)
02647     {
02648       memset(&objhandle, '\0', sizeof(objhandle));
02649       memset(&bfhandle, '\0', sizeof(bfhandle));
02650       memset(&cosinfo, '\0', sizeof(cosinfo));
02651       memset(&sclassinfo, '\0', sizeof(sclassinfo));
02652       if(AttrsOut != NULL)
02653         {
02654           memset(&ret_attrs, '\0', sizeof(ret_attrs));
02655           ret_attr_bits = API_VAttrAttrBits;
02656         }
02657 
02658       error = API_core_OpenFile(ThreadContext,
02659                                 RequestID,
02660                                 Ucred,
02661                                 ParentHandle,
02662                                 Path,
02663                                 oflags,
02664                                 new_attr_bits,
02665                                 &new_attrs,
02666                                 HintsIn,
02667                                 HintsPri,
02668                                 ret_attr_bits,
02669                                 &ret_attrs, &cosinfo, &sclassinfo, &bfhandle, &objhandle);
02670     }
02671 
02672   if(error == 0)
02673     {
02674       int lstndesc;
02675       data_addr_t lstnaddr;
02676 
02677       /*
02678        *  Get a socket and put out a listen for data transfers.
02679        */
02680 
02681       error = API_OpenListenDesc(API_TRANSFER_TCP, &lstndesc, &lstnaddr);
02682       if(error != HPSS_E_NOERROR)
02683         {
02684           API_DEBUG_FPRINTF(DebugFile, &RequestID,
02685                             "Could not get listen socket." " errno =%d\n", -error);
02686 
02687           API_LogMsg(function_name, RequestID, CS_DEBUG,
02688                      COMMUNICATION_ERROR, WARNING, API_OPEN_LISTEN_DESC_ERROR, error);
02689         }
02690       else
02691         {
02692 
02693           /*
02694            *  We found an open table descriptor
02695            *  Fill in the descriptor with the open file state.
02696            */
02697 
02698           open_ftptr->Type = BFS_OPEN_HANDLE;
02699           open_bfdesc_ptr->FilesetCOS = FilesetCOS;
02700           open_ftptr->ObjectHandle = objhandle;
02701           open_bfdesc_ptr->BFHandle = bfhandle;
02702           open_bfdesc_ptr->Offset = cast64m(0);
02703           open_bfdesc_ptr->OpenFlag = Oflag;
02704           open_bfdesc_ptr->DataConnPtr = NULL;
02705           open_bfdesc_ptr->CoreServerUUID = objhandle.CoreServerUUID;
02706           open_bfdesc_ptr->Updates = 0;
02707           open_bfdesc_ptr->Mutex = pthread_mutex_initializer;
02708           open_bfdesc_ptr->Cond = pthread_cond_initializer;
02709           open_bfdesc_ptr->ListenDesc = lstndesc;
02710           open_bfdesc_ptr->ListenAddr_u = lstnaddr;
02711 
02712           API_OpenThrdCntlDesc(open_bfdesc_ptr);
02713 
02714           /*
02715            * Mark the file table entry as not busy.
02716            */
02717 
02718           API_LockMutex(&ftptr->Mutex);
02719           open_ftptr->Flags = 0;
02720           API_UnlockMutex(&ftptr->Mutex);
02721 
02722           /*
02723            *  The file now exists, go ahead and convert
02724            *  the returned name server attributes.
02725            */
02726 
02727           if(AttrsOut != NULL)
02728             *AttrsOut = ret_attrs;
02729 
02730           if(HandleOut != NULL)
02731             *HandleOut = objhandle;
02732 
02733           if(HintsOut != NULL)
02734             {
02735               HintsOut->COSId = cosinfo.COSId;
02736               strncpy((char *)HintsOut->COSName,
02737                       (char *)cosinfo.COSName, HPSS_MAX_COS_NAME);
02738               HintsOut->Flags = cosinfo.Flags;
02739               HintsOut->OptimumAccessSize = cast64m(cosinfo.OptimumAccessSize);
02740               HintsOut->MinFileSize = cosinfo.MinFileSize;
02741               HintsOut->MaxFileSize = cosinfo.MaxFileSize;
02742               HintsOut->AccessFrequency = cosinfo.AccessFrequency;
02743               HintsOut->TransferRate = cosinfo.TransferRate;
02744               HintsOut->AvgLatency = cosinfo.AvgLatency;
02745               HintsOut->WriteOps = cosinfo.WriteOps;
02746               HintsOut->ReadOps = cosinfo.ReadOps;
02747               HintsOut->StageCode = cosinfo.StageCode;
02748               HintsOut->StripeWidth = sclassinfo.StripeWidth;
02749               HintsOut->StripeLength = sclassinfo.StripeLength;
02750             }
02751         }
02752     }
02753 
02754   if(error != 0)
02755     {
02756       /*
02757        *  We had an open problem. Free up the allocated slot.
02758        */
02759 
02760       API_LockMutex(&ftptr->Mutex);
02761 
02762       open_ftptr->Type = NO_OPEN_HANDLE;
02763       open_ftptr->Flags = 0;
02764       ftptr->TotalOpens--;
02765       ftptr->NumOpenDesc--;
02766 
02767       API_UnlockMutex(&ftptr->Mutex);
02768 
02769       return (error);
02770     }
02771 
02772   return (fildes);
02773 }
02774 
02775 static int HPSSFSAL_Common_Create_File(apithrdstate_t * ThreadContext,  /* IN - thread context */
02776                                        hpss_reqid_t RequestID,  /* IN - request id */
02777                                        ns_ObjHandle_t * ParentHandle,   /* IN - parent object handle */
02778                                        char *Path,      /* IN - Path to file to be opened */
02779                                        sec_cred_t * Ucred,      /* IN - user credentials */
02780                                        acct_rec_t * ParentAcct, /* IN - parent account code */
02781                                        mode_t Mode,     /* IN - create mode */
02782                                        hpss_cos_hints_t * HintsIn,      /* IN - Desired class of service */
02783                                        hpss_cos_priorities_t * HintsPri,        /* IN - Priorities of hint struct */
02784                                        hpss_cos_hints_t * HintsOut,     /* OUT - Granted class of service */
02785                                        hpss_Attrs_t * AttrsOut, /* OUT - returned attributes */
02786                                        ns_ObjHandle_t * HandleOut)
02787 {
02788   static char function_name[] = "Common_Create_File";
02789   long error;                   /* return error */
02790   ns_ObjHandle_t obj_handle;    /* object handle */
02791   hpss_AttrBits_t select_flags; /* retrieve object attr bits */
02792   hpss_AttrBits_t update_flags; /* updated object attr bits */
02793   hpss_Attrs_t new_attr;        /* object attributes */
02794   hpss_Attrs_t attr_out;        /* returned object attributes */
02795   hpss_cos_md_t cos_info;       /* returned COS information */
02796   hpss_sclass_md_t sclass_info; /* returned level 0 sclass info */
02797   acct_rec_t cur_acct_code;     /* current site account code */
02798   acct_rec_t new_acct_code;     /* validated account code */
02799   hpss_uuid_t site_id;          /* site */
02800   acct_rec_t pacct;             /* parent account */
02801 
02802   /*
02803    *  Do account validation.
02804    */
02805 
02806   error = API_DetermineAcct(Ucred,
02807                             ThreadContext,
02808                             ParentHandle->CoreServerUUID,
02809                             RequestID, &site_id, &cur_acct_code);
02810   if(error != 0)
02811     {
02812       API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't"
02813                         " get the account code from the given"
02814                         " information: error= %d\n", function_name, error);
02815       return (error);
02816     }
02817 
02818   /*
02819    * Try to get an account for the specified pareht handle 
02820    */
02821   if(ParentAcct == NULL)
02822     {
02823       ParentAcct = &pacct;
02824       if((error = API_GetAcctForParent(ThreadContext,
02825                                        RequestID, ParentHandle, &pacct)) != 0)
02826         {
02827           API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't"
02828                             " get the account id for the given"
02829                             " parent handle: error= %d\n", function_name, error);
02830           return (error);
02831         }
02832     }
02833 
02834   error = av_cli_ValidateCreate(site_id,
02835                                 RequestID,
02836                                 Ucred->RealmId,
02837                                 Ucred->Uid,
02838                                 Ucred->Gid, cur_acct_code, *ParentAcct, &new_acct_code);
02839   if(error != 0)
02840     {
02841       API_DEBUG_FPRINTF(DebugFile, &RequestID, "%s: couldn't validate"
02842                         " the account code: error= %d\n", function_name, error);
02843       return (-EPERM);
02844     }
02845 
02846   Ucred->CurAccount = new_acct_code;
02847 
02848   /*
02849    *  Create the file in HPSS.
02850    */
02851 
02852   memset(&new_attr, 0, sizeof(new_attr));
02853   memset(&attr_out, 0, sizeof(attr_out));
02854   memset(&obj_handle, 0, sizeof(obj_handle));
02855 
02856   memset(&cos_info, 0, sizeof(cos_info));
02857   memset(&sclass_info, 0, sizeof(sclass_info));
02858   memset(&obj_handle, 0, sizeof(obj_handle));
02859 
02860   /*
02861    * Setup the input attributes.
02862    */
02863 
02864   API_ConvertPosixModeToMode(Mode & ~ThreadContext->Umask, &new_attr);
02865   new_attr.Account = new_acct_code;
02866   update_flags = API_AddRegisterValues(cast64m(0),
02867                                        CORE_ATTR_USER_PERMS,
02868                                        CORE_ATTR_GROUP_PERMS,
02869                                        CORE_ATTR_OTHER_PERMS,
02870                                        CORE_ATTR_MODE_PERMS, CORE_ATTR_ACCOUNT, -1);
02871 
02872   /*
02873    *  Only request returned attributes if we have somewhere to
02874    *  put them.
02875    */
02876 
02877   if(AttrsOut != (hpss_Attrs_t *) NULL)
02878     select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX);
02879   else
02880     select_flags = cast64m(0);
02881 
02882   error = API_core_CreateFile(ThreadContext,
02883                               RequestID,
02884                               Ucred,
02885                               ParentHandle,
02886                               Path,
02887                               HintsIn,
02888                               HintsPri,
02889                               update_flags,
02890                               &new_attr,
02891                               select_flags,
02892                               &attr_out, &obj_handle, &cos_info, &sclass_info);
02893 
02894   if(error == 0 && HintsOut != NULL)
02895     {
02896       /*
02897        *  The file now exists, go ahead and convert
02898        *  the returned hints, if requested.
02899        */
02900 
02901       HintsOut->COSId = cos_info.COSId;
02902       strncpy((char *)HintsOut->COSName, (char *)cos_info.COSName, HPSS_MAX_COS_NAME);
02903       HintsOut->OptimumAccessSize = cast64m(cos_info.OptimumAccessSize);
02904       HintsOut->MinFileSize = cos_info.MinFileSize;
02905       HintsOut->MaxFileSize = cos_info.MaxFileSize;
02906       HintsOut->AccessFrequency = cos_info.AccessFrequency;
02907       HintsOut->TransferRate = cos_info.TransferRate;
02908       HintsOut->AvgLatency = cos_info.AvgLatency;
02909       HintsOut->WriteOps = cos_info.WriteOps;
02910       HintsOut->ReadOps = cos_info.ReadOps;
02911       HintsOut->StageCode = cos_info.StageCode;
02912       HintsOut->StripeWidth = sclass_info.StripeWidth;
02913       HintsOut->StripeLength = sclass_info.StripeLength;
02914     }
02915 
02916   if(error == 0)
02917     {
02918       /*
02919        *  The file now exists
02920        */
02921       if(AttrsOut != NULL)
02922         *AttrsOut = attr_out;
02923       if(HandleOut != NULL)
02924         *HandleOut = obj_handle;
02925     }
02926 
02927   return (error);
02928 }
02929 
02930 #endif