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 00011 /* 00012 * For determining if a returned access ticket is NULL. 00013 */ 00014 00015 TYPE_TOKEN_HPSS null_ticket; 00016 00017 #if HPSS_MAJOR_VERSION < 7 00018 00019 static int 00020 HPSSFSAL_Common_Symlink(apithrdstate_t * ThreadContext, 00021 hpss_reqid_t RequestID, 00022 ns_ObjHandle_t * ObjHandle, 00023 TYPE_CRED_HPSS * Ucred, 00024 char *Path, 00025 api_cwd_stack_t * CwdStack, 00026 char *Contents, 00027 ns_ObjHandle_t * HandleOut, hpss_Attrs_t * AttrsOut) 00028 { 00029 static char function_name[] = "HPSSFSAL_Common_Symlink"; 00030 00031 #if HPSS_MAJOR_VERSION == 5 00032 volatile long error = 0; /* return error */ 00033 #elif HPSS_MAJOR_VERSION >= 6 00034 signed32 error = 0; /* return error */ 00035 #endif 00036 00037 call_type_t call_type; /* interface to call */ 00038 TYPE_TOKEN_HPSS ta; /* security token */ 00039 ns_ObjHandle_t parent_handle; /* parent object handle */ 00040 u_signed64 parent_attr_bits; /* object attribute bits */ 00041 hpss_Attrs_t parent_attrs; /* new object attributes */ 00042 char *file; /* name of the new object */ 00043 char *parent; /* name of existing parent */ 00044 ns_ObjHandle_t new_handle; /* new object handle */ 00045 ns_ObjHandle_t ret_handle; /* returned new object handle */ 00046 u_signed64 new_attr_bits; /* object attribute bits */ 00047 hpss_Attrs_t new_attrs; /* new object attributes */ 00048 00049 /* 00050 * Allocate memory for object name and parent 00051 */ 00052 00053 file = (char *)malloc(HPSS_MAX_FILE_NAME); 00054 if(file == NULL) 00055 return (-ENOMEM); 00056 00057 parent = (char *)malloc(HPSS_MAX_PATH_NAME); 00058 if(parent == NULL) 00059 { 00060 free(file); 00061 return (-ENOMEM); 00062 } 00063 00064 /* 00065 * Divide the object component from the rest of the path 00066 */ 00067 00068 error = API_DivideFilePath(Path, parent, file); 00069 00070 free(parent); 00071 if(error != 0) 00072 { 00073 free(file); 00074 return (error); 00075 } 00076 00077 /* 00078 * Traverse the path to the parent and get 00079 * it's attributes and handle. 00080 */ 00081 00082 (void)memset(&ta, 0, sizeof(TYPE_TOKEN_HPSS)); 00083 (void)memset(&parent_handle, 0, sizeof(parent_handle)); 00084 (void)memset(&parent_attrs, 0, sizeof(parent_attrs)); 00085 00086 parent_attr_bits = API_AddRegisterValues(cast64m(0), 00087 CORE_ATTR_TYPE, 00088 CORE_ATTR_FILESET_TYPE, 00089 CORE_ATTR_FILESET_ID, 00090 CORE_ATTR_GATEWAY_UUID, 00091 CORE_ATTR_DM_HANDLE, 00092 CORE_ATTR_DM_HANDLE_LENGTH, -1); 00093 00094 error = API_TraversePath(ThreadContext, 00095 RequestID, 00096 Ucred, 00097 ObjHandle, 00098 Path, 00099 CwdStack, 00100 API_CHASE_ALL, 00101 0, 00102 0, 00103 cast64m(0), 00104 parent_attr_bits, 00105 API_NULL_CWD_STACK, 00106 NULL, NULL, &parent_handle, &parent_attrs, &ta, NULL, NULL); 00107 00108 if(error == 0) 00109 error = -EEXIST; 00110 else if(error == -ENOENT && memcmp(&ta, &null_ticket, sizeof(ta)) != 0) 00111 error = 0; 00112 else 00113 { 00114 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00115 "%s: Could not find object.\n", function_name); 00116 } 00117 00118 if(error == 0) 00119 { 00120 00121 /* 00122 * Call this function to determine which interface 00123 * to call (DMAP Gateway or the Core Server) depending 00124 * on if the object is DMAP mapped, which version of 00125 * the library this is, what type of DMAP file set 00126 * this is (sync or backup). 00127 */ 00128 #if HPSS_MAJOR_VERSION == 5 00129 call_type = API_DetermineCall(parent_attrs.FilesetType, (long *)&error); 00130 #elif HPSS_MAJOR_VERSION == 6 00131 call_type = API_DetermineCall(parent_attrs.FilesetType, &error); 00132 #endif 00133 00134 if(call_type == API_CALL_DMG) 00135 { 00136 /* 00137 * Here we are being called by a non-gateway client and 00138 * trying to link a object in a DMAP file set. 00139 */ 00140 00141 #if defined (API_DMAP_SUPPORT) && !defined (API_DMAP_GATEWAY) 00142 00143 error = API_dmg_Symlink(ThreadContext, RequestID, Ucred, &parent_attrs.GatewayUUID, parent_attrs.FilesetId, parent_attrs.DMHandle, parent_attrs.DMHandleLength, file, Contents, NULL, /* not used */ 00144 NULL); /* not used */ 00145 #else 00146 error = EACCES; 00147 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00148 "%s: No dmap support compiled in.\n", function_name); 00149 #endif 00150 00151 } 00152 else if(call_type == API_CALL_HPSS) 00153 { 00154 /* 00155 * Here we are being call by either a gateway client 00156 * or a non-gateway client trying to link a object 00157 * in a non-DMAP file set. 00158 */ 00159 00160 error = API_core_MkSymLink(ThreadContext, 00161 RequestID, 00162 Ucred, 00163 &parent_handle, 00164 file, 00165 &parent_attrs.FilesetId, Contents, &new_handle); 00166 00167 if(error != 0) 00168 { 00169 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00170 "%s: can't make symlink, error=%d\n,", 00171 function_name, error); 00172 } 00173 00174 } 00175 00176 /* 00177 * Call type is not DMG or HPSS. 00178 */ 00179 00180 else 00181 { 00182 if(error == 0) 00183 error = EIO; 00184 00185 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00186 "%s: Bad case from DetermineCall().\n", function_name); 00187 } 00188 00189 /* 00190 * If requested, return the vattr for the newly created 00191 * link 00192 */ 00193 00194 if(error == 0 && AttrsOut != (hpss_Attrs_t *) NULL) 00195 { 00196 new_attr_bits = cast64m(0); 00197 new_attr_bits = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX); 00198 (void)memset(&ret_handle, 0, sizeof(ret_handle)); 00199 (void)memset(&new_attrs, 0, sizeof(new_attrs)); 00200 (void)memset(&ta, 0, sizeof(ta)); 00201 00202 error = API_TraversePath(ThreadContext, 00203 RequestID, 00204 Ucred, 00205 &new_handle, 00206 NULL, 00207 API_NULL_CWD_STACK, 00208 API_CHASE_NONE, 00209 0, 00210 0, 00211 new_attr_bits, 00212 cast64m(0), 00213 API_NULL_CWD_STACK, 00214 &ret_handle, &new_attrs, NULL, NULL, &ta, NULL, NULL); 00215 00216 if(error != 0) 00217 { 00218 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00219 "%s: Could not get attributes.\n", function_name); 00220 } 00221 else 00222 { 00223 *AttrsOut = new_attrs; 00224 *HandleOut = new_handle; 00225 } 00226 } 00227 } 00228 00229 free(file); 00230 return (error); 00231 } 00232 #else /* from v7 */ 00233 00234 static int 00235 HPSSFSAL_Common_Symlink(apithrdstate_t * ThreadContext, 00236 hpss_reqid_t RequestID, 00237 ns_ObjHandle_t * ObjHandle, 00238 sec_cred_t * Ucred, 00239 char *Path, 00240 api_cwd_stack_t * CwdStack, 00241 char *Contents, 00242 ns_ObjHandle_t * HandleOut, hpss_Attrs_t * AttrsOut) 00243 { 00244 static char function_name[] = "Common_Symlink"; 00245 signed32 error = 0; /* return error */ 00246 ns_ObjHandle_t parent_handle; /* parent object handle */ 00247 char *file; /* name of the new object */ 00248 char *parentpath; /* name of existing parent */ 00249 hpss_AttrBits_t attr_bits; /* parent attributes bits */ 00250 hpss_Attrs_t attrs; /* parent attributes */ 00251 ns_ObjHandle_t *hndl_ptr = ObjHandle; /* parent handle pointer */ 00252 ns_ObjHandle_t new_handle; /* new object handle */ 00253 ns_ObjHandle_t ret_handle; /* returned new object handle */ 00254 u_signed64 new_attr_bits; /* object attribute bits */ 00255 hpss_Attrs_t new_attrs; /* new object handle */ 00256 00257 /* 00258 * Allocate memory for object name and parent name 00259 */ 00260 00261 file = (char *)malloc(HPSS_MAX_FILE_NAME); 00262 if(file == NULL) 00263 return (-ENOMEM); 00264 00265 parentpath = (char *)malloc(HPSS_MAX_PATH_NAME); 00266 if(parentpath == NULL) 00267 { 00268 free(file); 00269 return (-ENOMEM); 00270 } 00271 00272 /* 00273 * Divide the object component from the rest of the path 00274 */ 00275 00276 if((error = API_DivideFilePath(Path, parentpath, file)) != 0) 00277 { 00278 free(file); 00279 free(parentpath); 00280 return (error); 00281 } 00282 00283 if(API_PATH_NEEDS_TRAVERSAL(parentpath)) 00284 { 00285 /* 00286 * If there is a path provided then, then lookup 00287 * the parent handle 00288 */ 00289 00290 attr_bits = API_AddRegisterValues(cast64m(0), CORE_ATTR_TYPE, -1); 00291 00292 memset(&parent_handle, 0, sizeof(parent_handle)); 00293 memset(&attrs, '\0', sizeof(attrs)); 00294 00295 /* 00296 * Traverse the path to the parent and get it's handle. 00297 */ 00298 00299 error = API_TraversePath(ThreadContext, 00300 RequestID, 00301 Ucred, 00302 ObjHandle, 00303 parentpath, 00304 CwdStack, 00305 API_CHASE_ALL, 00306 0, 00307 0, 00308 attr_bits, 00309 cast64m(0), 00310 API_NULL_CWD_STACK, 00311 &parent_handle, 00312 &attrs, 00313 (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL); 00314 00315 if(error == 0) 00316 { 00317 if(attrs.Type != NS_OBJECT_TYPE_DIRECTORY) 00318 error = -ENOTDIR; 00319 else 00320 { 00321 hndl_ptr = &parent_handle; 00322 } 00323 } 00324 } 00325 else if(API_PATH_IS_ROOT(parentpath)) 00326 { 00327 /* If needed, use the root handle */ 00328 error = API_InitRootHandle(ThreadContext, RequestID, &hndl_ptr); 00329 } 00330 00331 if(error == 0) 00332 { 00333 error = API_core_MkSymLink(ThreadContext, 00334 RequestID, Ucred, hndl_ptr, file, Contents, &new_handle); 00335 00336 if(error != 0) 00337 { 00338 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00339 "%s: can't make symlink, error=%d\n,", function_name, error); 00340 } 00341 } 00342 00343 /* 00344 * If requested, return the vattr for the newly created link 00345 */ 00346 00347 if(error == 0 && AttrsOut != (hpss_Attrs_t *) NULL) 00348 { 00349 new_attr_bits = API_VAttrAttrBits; 00350 (void)memset(&ret_handle, 0, sizeof(ret_handle)); 00351 (void)memset(&new_attrs, 0, sizeof(new_attrs)); 00352 00353 error = API_TraversePath(ThreadContext, 00354 RequestID, 00355 Ucred, 00356 &new_handle, 00357 NULL, 00358 API_NULL_CWD_STACK, 00359 API_CHASE_NONE, 00360 0, 00361 0, 00362 new_attr_bits, 00363 cast64m(0), 00364 API_NULL_CWD_STACK, 00365 &ret_handle, &new_attrs, NULL, NULL, NULL, NULL); 00366 00367 if(error != 0) 00368 { 00369 API_DEBUG_FPRINTF(DebugFile, &RequestID, 00370 "%s: Could not get attributes.\n", function_name); 00371 } 00372 else 00373 { 00374 *AttrsOut = new_attrs; 00375 *HandleOut = ret_handle; 00376 } 00377 } 00378 00379 free(file); 00380 free(parentpath); 00381 00382 return (error); 00383 } 00384 00385 #endif 00386 00387 int HPSSFSAL_SymlinkHandle(ns_ObjHandle_t * ObjHandle, /* IN - Handle of existing file */ 00388 char *Contents, /* IN - Desired contents of the link */ 00389 char *Path, /* IN - New name of the symbolic link */ 00390 TYPE_CRED_HPSS * Ucred, /* IN - pointer to user credentials */ 00391 ns_ObjHandle_t * HandleOut, /* OUT - Handle of crfeated link */ 00392 hpss_Attrs_t * AttrsOut) /* OUT - symbolic link attributes */ 00393 { 00394 long error = 0; 00395 apithrdstate_t *threadcontext; 00396 hpss_reqid_t rqstid; 00397 TYPE_CRED_HPSS *ucred_ptr; 00398 00399 API_ENTER("HPSSFSAL_SymlinkHandle"); 00400 00401 /* 00402 * Initialize the thread if not already initialized. 00403 * Get a pointer back to the thread specific context. 00404 */ 00405 00406 error = API_ClientAPIInit(&threadcontext); 00407 if(error != 0) 00408 API_RETURN(error); 00409 00410 /* 00411 * Check that the object handle is not NULL. 00412 */ 00413 00414 if(ObjHandle == (ns_ObjHandle_t *) NULL) 00415 API_RETURN(-EINVAL); 00416 00417 /* 00418 * We need an path to create the new symlink 00419 */ 00420 00421 if(Path == NULL) 00422 API_RETURN(-EFAULT); 00423 00424 if(*Path == '\0') 00425 API_RETURN(-ENOENT); 00426 00427 /* 00428 * Need to have contents for the symlink 00429 */ 00430 00431 if(Contents == NULL) 00432 API_RETURN(-EFAULT); 00433 00434 /* 00435 * If user credentials were not passed, use the ones in the 00436 * current thread context. 00437 */ 00438 00439 if(Ucred == (TYPE_CRED_HPSS *) NULL) 00440 ucred_ptr = &threadcontext->UserCred; 00441 else 00442 ucred_ptr = Ucred; 00443 00444 /* 00445 * Get a valid request id. 00446 */ 00447 00448 rqstid = API_GetUniqueRequestID(); 00449 00450 /* 00451 * Call HPSSFSAL_Common_Symlink() to perform the majority of the common symbolic 00452 * link processing. 00453 */ 00454 00455 error = HPSSFSAL_Common_Symlink(threadcontext, 00456 rqstid, 00457 ObjHandle, 00458 ucred_ptr, 00459 Path, 00460 API_NULL_CWD_STACK, Contents, HandleOut, AttrsOut); 00461 00462 API_RETURN(error); 00463 }