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 <u_signed64.h> 00008 #include <hpssclapiext.h> 00009 #include <api_internal.h> 00010 #include <acct_av_lib.h> 00011 00012 /* 00013 * Prototype(s) for static routines. 00014 */ 00015 00016 static int 00017 HPSSFSAL_Common_Mkdir(apithrdstate_t * ThreadContext, 00018 ns_ObjHandle_t * ObjHandle, 00019 char *Path, 00020 api_cwd_stack_t * CwdStack, 00021 int Mode, 00022 TYPE_CRED_HPSS * Ucred, 00023 ns_ObjHandle_t * RetObjHandle, hpss_Attrs_t * RetAttrs); 00024 00025 /*============================================================================ 00026 * 00027 * Function: hpss_MkdirHandle 00028 * 00029 * Synopsis: 00030 * 00031 * int 00032 * HPSSFSAL_MkdirHandle( 00033 * ns_ObjHandle_t *ObjHandle, ** IN - handle of parent directory 00034 * char *Path, ** IN - path of directory 00035 * mode_t Mode, ** IN - perm bits for new directory 00036 * hsec_UserCred_t *Ucred, ** IN - user credentials 00037 * ns_ObjHandle_t *HandleOut, ** OUT - returned object handle 00038 * hpss_Attrs_t *AttrsOut) ** OUT - returned VFS attributes 00039 * 00040 * Description: 00041 * 00042 * The 'hpss_MkdirHandle' function creates a new directory with the name 00043 * 'Path', taken relative to the directory indicated by 'ObjHandle'. 00044 * The directory permission bits of the new directory are initialized by 00045 * 'Mode', and modified by the file creation mask of the thread. The 00046 * newly created directory's object handle and attributes are 00047 * returned in the areas pointed to by 'RetObjHandle' and 00048 * 'RetVAttrs', respectively. 00049 * 00050 * Other Inputs: 00051 * None. 00052 * 00053 * Outputs: 00054 * 0 - No error. New directory created. 00055 * 00056 * Interfaces: 00057 * DCE pthreads, DCE/RPC, HPSSFSAL_Common_Mkdir. 00058 * 00059 * Resources Used: 00060 * 00061 * Limitations: 00062 * 00063 * Assumptions: 00064 * 00065 * Notes: 00066 * 00067 *-------------------------------------------------------------------------*/ 00068 00069 int HPSSFSAL_MkdirHandle(ns_ObjHandle_t * ObjHandle, /* IN - handle of parent directory */ 00070 char *Path, /* IN - path of directory */ 00071 mode_t Mode, /* IN - perm bits for new directory */ 00072 TYPE_CRED_HPSS * Ucred, /* IN - user credentials */ 00073 ns_ObjHandle_t * HandleOut, /* OUT - returned object handle */ 00074 hpss_Attrs_t * AttrsOut) /* OUT - returned attributes */ 00075 { 00076 long error = 0; 00077 apithrdstate_t *threadcontext; 00078 TYPE_CRED_HPSS *ucred_ptr; 00079 00080 API_ENTER("hpss_MkdirHandle"); 00081 00082 /* 00083 * Initialize the thread if not already initialized. 00084 * Get a pointer back to the thread specific context. 00085 */ 00086 00087 error = API_ClientAPIInit(&threadcontext); 00088 if(error != 0) 00089 API_RETURN(error); 00090 00091 /* 00092 * Check that the object handle is not NULL. 00093 */ 00094 00095 if(ObjHandle == (ns_ObjHandle_t *) NULL) 00096 API_RETURN(-EINVAL); 00097 00098 /* 00099 * Check that there is a name for the new object 00100 */ 00101 00102 if(Path == NULL) 00103 API_RETURN(-EFAULT); 00104 00105 if(*Path == '\0') 00106 API_RETURN(-ENOENT); 00107 00108 /* 00109 * If user credentials were not passed, use the ones in the 00110 * current thread context. 00111 */ 00112 00113 if(Ucred == (TYPE_CRED_HPSS *) NULL) 00114 ucred_ptr = &threadcontext->UserCred; 00115 else 00116 ucred_ptr = Ucred; 00117 00118 error = HPSSFSAL_Common_Mkdir(threadcontext, 00119 ObjHandle, 00120 Path, 00121 API_NULL_CWD_STACK, Mode, ucred_ptr, HandleOut, AttrsOut); 00122 00123 API_RETURN(error); 00124 } 00125 00126 /*============================================================================ 00127 * 00128 * Function: HPSSFSAL_Common_Mkdir 00129 * 00130 * Synopsis: 00131 * 00132 * static int 00133 * HPSSFSAL_Common_Mkdir( 00134 * apithrdstate_t *ThreadContext, ** IN - thread context 00135 * ns_ObjHandle_t *ObjHandle, ** IN - handle of parent directory 00136 * char *Path, ** IN - path of directory 00137 * mode_t Mode, ** IN - perm bits for new directory 00138 * hsec_UserCred_t *Ucred, ** IN - user credentials 00139 * ns_ObjHandle_t *RetObjHandle, ** OUT - returned object handle 00140 * hpss_Attrs_t *RetAttrs) ** OUT - returned attributes 00141 * 00142 * Description: 00143 * 00144 * The 'HPSSFSAL_Common_Mkdir' function performs the common processing for 00145 * hpss_Mkdir, hpss_MkdirHandle, and hpss_MkdirDMHandle functions. 00146 * 00147 * Other Inputs: 00148 * None. 00149 * 00150 * Outputs: 00151 * 0 - No error. New directory created. 00152 * 00153 * Interfaces: 00154 * DCE pthreads, DCE/RPC, API_core_MkDir, API_ConvertPosixModeToMode, 00155 * API_TraversePath, API_DetermineAcct, av_cli_ValidateCreate, 00156 * API_AddRegisterValues 00157 * 00158 * Resources Used: 00159 * 00160 * Limitations: 00161 * 00162 * Assumptions: 00163 * 00164 * Notes: 00165 * 00166 *-------------------------------------------------------------------------*/ 00167 00168 static int 00169 HPSSFSAL_Common_Mkdir(apithrdstate_t * ThreadContext, 00170 ns_ObjHandle_t * ObjHandle, 00171 char *Path, 00172 api_cwd_stack_t * CwdStack, 00173 int Mode, 00174 TYPE_CRED_HPSS * Ucred, 00175 ns_ObjHandle_t * RetObjHandle, hpss_Attrs_t * RetAttrs) 00176 { 00177 #if HPSS_MAJOR_VERSION < 7 00178 call_type_t call_type; 00179 #endif 00180 #if HPSS_MAJOR_VERSION == 5 00181 volatile long error = 0; /* return error */ 00182 #else 00183 signed32 error = 0; /* return error */ 00184 #endif 00185 static char function_name[] = "HPSSFSAL_Common_Mkdir"; 00186 ns_ObjHandle_t objhandle_parent; 00187 ns_ObjHandle_t objhandle_newdir; 00188 hpss_Attrs_t attr_parent; 00189 hpss_Attrs_t attr_newdir_in; 00190 hpss_Attrs_t attr_newdir_out; 00191 char *path_parent; 00192 char *path_newdir; 00193 retry_cb_t retry_cb; 00194 hpss_reqid_t rqstid; 00195 hpss_AttrBits_t select_flags; 00196 hpss_AttrBits_t update_flags; 00197 acct_rec_t new_acct_code; 00198 acct_rec_t temp_acct_code; 00199 TYPE_UUID_HPSS siteId; 00200 TYPE_TOKEN_HPSS ta; 00201 #if defined ( API_DMAP_SUPPORT ) && !defined ( API_DMAP_GATEWAY ) 00202 byte dm_handle[MAX_DMEPI_HANDLE_SIZE]; 00203 unsigned32 dm_handle_length; 00204 #endif 00205 00206 API_ENTER(function_name); 00207 00208 /* 00209 * Break the path into a path and a name, so that 00210 * we can get information about the parent. 00211 */ 00212 00213 path_parent = malloc(HPSS_MAX_PATH_NAME); 00214 if(path_parent == NULL) 00215 { 00216 return (-ENOMEM); 00217 } 00218 00219 path_newdir = malloc(HPSS_MAX_PATH_NAME); 00220 if(path_newdir == NULL) 00221 { 00222 free(path_parent); 00223 return (-ENOMEM); 00224 } 00225 00226 error = API_DivideFilePath(Path, path_parent, path_newdir); 00227 00228 if(error != 0) 00229 { 00230 free(path_parent); 00231 free(path_newdir); 00232 return (error); 00233 } 00234 00235 /* 00236 * Get a valid request id. 00237 */ 00238 00239 rqstid = API_GetUniqueRequestID(); 00240 00241 /* 00242 * Get an object handle and ns attributes for the parent 00243 * directory in which the new directory is to be created. 00244 * Determine from the attributes of the parent directory 00245 * whether it is dmap managed or not, and from that determine 00246 * whether to call the dmap gateway or the name server to 00247 * create the new directory. 00248 */ 00249 00250 (void)memset(&attr_parent, 0, sizeof(attr_parent)); 00251 (void)memset(&objhandle_parent, 0, sizeof(objhandle_parent)); 00252 00253 select_flags = API_AddRegisterValues(cast64m(0), CORE_ATTR_ACCOUNT, 00254 #if HPSS_MAJOR_VERSION < 7 00255 CORE_ATTR_FILESET_ID, 00256 CORE_ATTR_FILESET_TYPE, 00257 CORE_ATTR_GATEWAY_UUID, 00258 CORE_ATTR_DM_HANDLE, CORE_ATTR_DM_HANDLE_LENGTH, 00259 #endif 00260 -1); 00261 00262 error = API_TraversePath(ThreadContext, 00263 rqstid, 00264 Ucred, 00265 ObjHandle, 00266 path_parent, 00267 CwdStack, 00268 API_CHASE_ALL, 00269 0, 00270 0, 00271 select_flags, 00272 cast64m(0), 00273 API_NULL_CWD_STACK, &objhandle_parent, &attr_parent, 00274 #if HPSS_MAJOR_VERSION < 7 00275 NULL, 00276 #endif 00277 NULL, NULL, NULL, NULL); 00278 00279 if(error != 0) 00280 { 00281 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00282 "%s: Could not get attributes.\n", function_name); 00283 } 00284 else 00285 { 00286 /* 00287 * Check to see if we need to return the attributes of 00288 * the newly created directory and set up the select flags 00289 * appropriately. 00290 */ 00291 00292 if(RetAttrs != (hpss_Attrs_t *) NULL) 00293 { 00294 select_flags = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX); 00295 } 00296 else 00297 { 00298 select_flags = cast64m(0); 00299 } 00300 00301 /* 00302 * Determine the appropriate accounting to use. 00303 */ 00304 00305 error = API_DetermineAcct(Ucred, 00306 ThreadContext, 00307 objhandle_parent.CoreServerUUID, 00308 rqstid, &siteId, &temp_acct_code); 00309 if(error != 0) 00310 { 00311 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00312 "%s: Could not determine which" 00313 " account to use.\n", function_name); 00314 } 00315 else 00316 { 00317 /* 00318 * Validate the account. 00319 */ 00320 #if HPSS_MAJOR_VERSION == 5 00321 error = av_cli_ValidateCreate(siteId, 00322 rqstid, 00323 Ucred->DCECellId, 00324 Ucred->SecPWent.Uid, 00325 Ucred->SecPWent.Gid, 00326 temp_acct_code, 00327 attr_parent.Account, &new_acct_code); 00328 #elif (HPSS_MAJOR_VERSION == 6) || (HPSS_MAJOR_VERSION == 7) 00329 error = av_cli_ValidateCreate(siteId, 00330 rqstid, 00331 Ucred->RealmId, 00332 Ucred->Uid, 00333 Ucred->Gid, 00334 temp_acct_code, 00335 attr_parent.Account, &new_acct_code); 00336 #endif 00337 00338 if(error != 0) 00339 { 00340 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00341 "%s: Could not validate" 00342 " the account.\n", function_name); 00343 } 00344 } 00345 } 00346 00347 if(error == 0) 00348 { 00349 00350 #if HPSS_MAJOR_VERSION < 7 00351 00352 /* 00353 * Do we call the dmap gateway or the name server? 00354 */ 00355 00356 #if HPSS_MAJOR_VERSION == 5 00357 call_type = API_DetermineCall(attr_parent.FilesetType, (long *)&error); 00358 #elif HPSS_MAJOR_VERSION == 6 00359 call_type = API_DetermineCall(attr_parent.FilesetType, &error); 00360 #endif 00361 00362 switch (call_type) 00363 { 00364 00365 case API_CALL_DMG: 00366 00367 #if defined ( API_DMAP_SUPPORT ) && !defined ( API_DMAP_GATEWAY ) 00368 /* 00369 * Call the dmap gateway to create the file. This will 00370 * have the side effect that the dmap will call us to 00371 * create the directory on the hpss side. By the time this 00372 * call returns, the directory will exist on both sides. 00373 */ 00374 00375 Ucred->CurAccount = new_acct_code; 00376 memset(dm_handle, 0, (sizeof(byte) * MAX_DMEPI_HANDLE_SIZE)); 00377 memset(&dm_handle_length, 0, sizeof(unsigned32)); 00378 00379 /* 00380 * The mode should have the directory bit set and 00381 * the umask bits reset. 00382 */ 00383 00384 Mode |= S_IFDIR; 00385 Mode &= ~(ThreadContext->Umask); 00386 00387 error = API_dmg_Create(ThreadContext, rqstid, Ucred, &attr_parent.GatewayUUID, attr_parent.FilesetId, attr_parent.DMHandle, attr_parent.DMHandleLength, path_newdir, Mode, NS_OBJECT_TYPE_DIRECTORY, NULL, /* cos hints in */ 00388 NULL, /* cos hints priority */ 00389 dm_handle, (unsigned32 *) & dm_handle_length, NULL); /* cos hints out */ 00390 00391 if(error != 0) 00392 { 00393 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00394 "%s: API_dmg_Create failed.\n", function_name); 00395 } 00396 else 00397 { 00398 /* 00399 * If the caller asked for them, obtain the hpss attributes 00400 * and an object handle for the new directory. 00401 * 00402 * ChaseSymlinks and ChaseJunctions shouldn't matter at 00403 * this point; the object should be a directory. 00404 */ 00405 00406 if(RetObjHandle || RetVAttrs) 00407 { 00408 error = API_TraversePath(ThreadContext, 00409 rqstid, 00410 Ucred, 00411 &objhandle_parent, 00412 path_newdir, 00413 CwdStack, 00414 API_CHASE_NONE, 00415 0, 00416 0, 00417 select_flags, 00418 cast64m(0), 00419 API_NULL_CWD_STACK, 00420 &objhandle_newdir, 00421 NULL, 00422 NULL, &attr_newdir_out, NULL, NULL, NULL); 00423 00424 if(error != 0) 00425 { 00426 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00427 "%s: Could not get attributes" 00428 " of new directory.\n", function_name); 00429 } 00430 } 00431 } 00432 #else 00433 error = EACCES; 00434 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00435 "%s: No dmap support compiled in.\n", function_name); 00436 #endif 00437 break; 00438 00439 case API_CALL_HPSS: 00440 00441 #endif /* HPSS < 7 */ 00442 00443 /* 00444 * Set up the parameters for the new directory. 00445 */ 00446 00447 (void)memset(&attr_newdir_out, 0, sizeof(attr_newdir_out)); 00448 (void)memset(&attr_newdir_in, 0, sizeof(attr_newdir_in)); 00449 00450 attr_newdir_in.Account = new_acct_code; 00451 00452 API_ConvertPosixModeToMode(Mode & ~(ThreadContext->Umask), &attr_newdir_in); 00453 00454 update_flags = API_AddRegisterValues(cast64m(0), 00455 CORE_ATTR_ACCOUNT, 00456 CORE_ATTR_USER_PERMS, 00457 CORE_ATTR_GROUP_PERMS, 00458 CORE_ATTR_OTHER_PERMS, -1); 00459 00460 #if defined(API_DMAP_GATEWAY) 00461 00462 /* 00463 * If the gateway is trying to create a directory on a 00464 * mirrored fileset, it must supply a UID & GID for 00465 * the directory. 00466 */ 00467 00468 if(attr_parent.FilesetType == CORE_FS_TYPE_MIRRORED) 00469 { 00470 attr_newdir_in.UID = Ucred->SecPWent.Uid; 00471 attr_newdir_in.GID = Ucred->SecPWent.Gid; 00472 update_flags = API_AddRegisterValues(update_flags, 00473 CORE_ATTR_UID, CORE_ATTR_GID, -1); 00474 } 00475 #endif 00476 /* 00477 * Note: The DM handle is not loaded here for non 00478 * HPSS filesets because the handle can only be 00479 * determined after the file is created on the 00480 * DMAP side. Therefore, the gateway must update 00481 * the directories attributes after the directory 00482 * is created. 00483 */ 00484 00485 error = API_core_MkDir(ThreadContext, 00486 rqstid, 00487 Ucred, 00488 &objhandle_parent, 00489 path_newdir, 00490 update_flags, 00491 &attr_newdir_in, 00492 select_flags, &attr_newdir_out, &objhandle_newdir); 00493 00494 if(error != 0) 00495 { 00496 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00497 "%s: Could not create directory" 00498 ", error=%d\n", function_name, error); 00499 00500 API_LogMsg(function_name, rqstid, CS_DEBUG, 00501 SOFTWARE_ERROR, NONE, API_REQUEST_ERROR, error); 00502 } 00503 #if HPSS_MAJOR_VERSION < 7 00504 break; 00505 00506 default: 00507 if(error == 0) 00508 error = EIO; 00509 API_DEBUG_FPRINTF(DebugFile, &rqstid, 00510 "%s: Bad case from DetermineCall().\n", function_name); 00511 break; 00512 } /* end switch */ 00513 #endif 00514 00515 } 00516 00517 /* end (if error == 0) */ 00518 /* 00519 * Convert the returned attributes, if necessary. 00520 */ 00521 if(RetAttrs != (hpss_Attrs_t *) NULL) 00522 { 00523 *RetAttrs = attr_newdir_out; 00524 } 00525 00526 if(RetObjHandle != (ns_ObjHandle_t *) NULL) 00527 *RetObjHandle = objhandle_newdir; 00528 00529 free(path_newdir); 00530 free(path_parent); 00531 00532 return (error); 00533 }