nfs-ganesha 1.4
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 #include <sys/types.h> 00005 #include <sys/stat.h> 00006 #include <fcntl.h> 00007 #include <unistd.h> 00008 #include <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