nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 00013 #ifdef HAVE_CONFIG_H 00014 #include "config.h" 00015 #endif 00016 00017 #ifdef _SOLARIS 00018 #include "solaris_port.h" 00019 #endif /* _SOLARIS */ 00020 00021 #include <string.h> 00022 #ifdef _USE_GSSRPC 00023 #include <gssrpc/rpc.h> 00024 #include <gssrpc/xdr.h> 00025 #else 00026 #include <rpc/rpc.h> 00027 #include <rpc/xdr.h> 00028 #endif 00029 #include "nfs4.h" 00030 00031 #include "fsal_internal.h" 00032 #include "fsal_convert.h" 00033 #include "fsal_common.h" 00034 00035 #include "nfs_proto_functions.h" 00036 #include "fsal_nfsv4_macros.h" 00037 #include "abstract_mem.h" 00038 00039 #ifdef _APPLE 00040 #define strnlen( s, l ) strlen( s ) 00041 #endif 00042 00081 fsal_status_t PROXYFSAL_open_by_name(fsal_handle_t * dirhandle, /* IN */ 00082 fsal_name_t * filename, /* IN */ 00083 fsal_op_context_t *context, /* IN */ 00084 fsal_openflags_t openflags, /* IN */ 00085 fsal_file_t * file_desc, /* OUT */ 00086 fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ 00087 ) 00088 { 00089 int rc; 00090 COMPOUND4args argnfs4; 00091 COMPOUND4res resnfs4; 00092 nfs_fh4 nfs4fh; 00093 bitmap4 bitmap; 00094 uint32_t bitmap_res[2]; 00095 uint32_t bitmap_open[2]; 00096 uint32_t bitmap_getattr_res[2]; 00097 uint32_t share_access; 00098 component4 name; 00099 char nameval[MAXNAMLEN]; 00100 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00101 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00102 00103 #define FSAL_OPEN_NB_OP_ALLOC 4 00104 #define FSAL_OPEN_VAL_BUFFER 1024 00105 00106 fsal_proxy_internal_fattr_t fattr_internal; 00107 fsal_attrib_list_t attributes; 00108 nfs_argop4 argoparray[FSAL_OPEN_NB_OP_ALLOC]; 00109 nfs_resop4 resoparray[FSAL_OPEN_NB_OP_ALLOC]; 00110 char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; 00111 fsal_status_t fsal_status; 00112 struct timeval timeout = TIMEOUTRPC; 00113 char owner_val[FSAL_PROXY_OWNER_LEN]; 00114 unsigned int owner_len = 0; 00115 00116 /* sanity checks. 00117 * note : file_attributes is optional. 00118 */ 00119 if(!dirhandle || !filename || !p_context || !file_descriptor) 00120 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00121 00122 PRINT_HANDLE("FSAL_open", dirhandle); 00123 00124 if(((proxyfsal_handle_t *)dirhandle)->data.object_type_reminder != FSAL_TYPE_DIR) 00125 { 00126 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_name); 00127 } 00128 00129 /* Create the owner */ 00130 snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu", 00131 getpid(), p_context, (unsigned long long int)p_context->file_counter); 00132 owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN); 00133 p_context->file_counter += 1; 00134 00135 /* Setup results structures */ 00136 argnfs4.argarray.argarray_val = argoparray; 00137 resnfs4.resarray.resarray_val = resoparray; 00138 argnfs4.minorversion = 0; 00139 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */ 00140 argnfs4.tag.utf8string_val = NULL; 00141 argnfs4.tag.utf8string_len = 0; 00142 argnfs4.argarray.argarray_len = 0; 00143 00144 fsal_internal_proxy_setup_fattr(&fattr_internal); 00145 00146 memset(&name, 0, sizeof(component4)); 00147 name.utf8string_val = nameval; 00148 name.utf8string_len = sizeof(nameval); 00149 if(fsal_internal_proxy_fsal_name_2_utf8(filename, &name) == FALSE) 00150 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00151 00152 00153 /* Get NFSv4 File handle */ 00154 if(fsal_internal_proxy_extract_fh(&nfs4fh, dirhandle) == FALSE) 00155 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00156 00157 bitmap.bitmap4_val = bitmap_open; 00158 bitmap.bitmap4_len = 2; 00159 00160 fsal_internal_proxy_create_fattr_bitmap(&bitmap); 00161 00162 share_access = 0; 00163 if((openflags & FSAL_O_RDWR) == FSAL_O_RDWR) 00164 share_access |= OPEN4_SHARE_ACCESS_BOTH; 00165 00166 if((openflags & FSAL_O_RDONLY) == FSAL_O_RDONLY) 00167 share_access |= OPEN4_SHARE_ACCESS_READ; 00168 00169 if(((openflags & FSAL_O_WRONLY) == FSAL_O_WRONLY) || 00170 ((openflags & FSAL_O_APPEND) == FSAL_O_APPEND)) 00171 share_access |= OPEN4_SHARE_ACCESS_WRITE; 00172 00173 /* >> you can check if this is a file if the information 00174 * is stored into the handle << */ 00175 #define FSAL_OPEN_IDX_OP_PUTFH 0 00176 #define FSAL_OPEN_IDX_OP_OPEN_NOCREATE 1 00177 #define FSAL_OPEN_IDX_OP_GETFH 2 00178 #define FSAL_OPEN_IDX_OP_GETATTR 3 00179 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00180 COMPOUNDV4_ARG_ADD_OP_OPEN_NOCREATE(argnfs4, file_descriptor->stateid.seqid, 00181 p_context->clientid, share_access, name, owner_val, 00182 owner_len); 00183 COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); 00184 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); 00185 00186 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 00187 OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res; 00188 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 00189 OPEN4res_u.resok4.attrset.bitmap4_len = 2; 00190 00191 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00192 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res; 00193 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00194 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 00195 00196 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00197 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 00198 (char *)&fattr_internal; 00199 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00200 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 00201 sizeof(fattr_internal); 00202 00203 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u. 00204 resok4.object.nfs_fh4_val = (char *)padfilehandle; 00205 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u. 00206 resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; 00207 00208 TakeTokenFSCall(); 00209 00210 /* Call the NFSv4 function */ 00211 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 00212 if(rc != RPC_SUCCESS) 00213 { 00214 ReleaseTokenFSCall(); 00215 Return(ERR_FSAL_IO, rc, INDEX_FSAL_open_by_name); 00216 } 00217 00218 ReleaseTokenFSCall(); 00219 00220 /* >> convert error code, and return on error << */ 00221 if(resnfs4.status != NFS4_OK) 00222 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open_by_name); 00223 00224 /* Use NFSv4 service function to build the FSAL_attr */ 00225 if(nfs4_Fattr_To_FSAL_attr(&attributes, 00226 &resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR]. 00227 nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. 00228 obj_attributes) != NFS4_OK) 00229 { 00230 FSAL_CLEAR_MASK(file_attributes->asked_attributes); 00231 FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00232 00233 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_name); 00234 } 00235 00236 if(file_attributes) 00237 { 00238 memcpy(file_attributes, &attributes, sizeof(attributes)); 00239 } 00240 00241 /* >> fill output struct << */ 00242 /* Build the handle */ 00243 if(fsal_internal_proxy_create_fh 00244 (&resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 00245 GETFH4res_u.resok4.object, FSAL_TYPE_FILE, attributes.fileid, 00246 (fsal_handle_t *) &file_descriptor->fhandle) == FALSE) 00247 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00248 00249 file_descriptor->openflags = openflags; 00250 file_descriptor->current_offset = 0; 00251 file_descriptor->pcontext = p_context; 00252 00253 /* Keep the returned stateid for later use */ 00254 file_descriptor->stateid.seqid = 00255 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 00256 OPEN4res_u.resok4.stateid.seqid; 00257 memcpy((char *)file_descriptor->stateid.other, 00258 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u. 00259 opopen.OPEN4res_u.resok4.stateid.other, 12); 00260 00261 /* See if a OPEN_CONFIRM is required */ 00262 if(resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 00263 OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM) 00264 { 00265 fsal_status = FSAL_proxy_open_confirm(file_descriptor); 00266 if(FSAL_IS_ERROR(fsal_status)) 00267 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_open_by_name); 00268 } 00269 00270 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open_by_name); 00271 } /* FSAL_open_by_name */ 00272 00309 fsal_status_t PROXYFSAL_open(fsal_handle_t * filehandle, /* IN */ 00310 fsal_op_context_t *context, /* IN */ 00311 fsal_openflags_t openflags, /* IN */ 00312 fsal_file_t * file_desc, /* OUT */ 00313 fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ 00314 ) 00315 { 00316 int rc; 00317 COMPOUND4args argnfs4; 00318 COMPOUND4res resnfs4; 00319 nfs_fh4 nfs4fh; 00320 bitmap4 bitmap; 00321 uint32_t bitmap_open[2]; 00322 uint32_t bitmap_getattr_res[2]; 00323 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00324 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00325 00326 #define FSAL_OPEN_STATELESS_NB_OP_ALLOC 2 00327 #define FSAL_OPEN_STATELESS_VAL_BUFFER 1024 00328 00329 fsal_proxy_internal_fattr_t fattr_internal; 00330 fsal_attrib_list_t attributes; 00331 nfs_argop4 argoparray[FSAL_OPEN_STATELESS_NB_OP_ALLOC]; 00332 nfs_resop4 resoparray[FSAL_OPEN_STATELESS_NB_OP_ALLOC]; 00333 struct timeval timeout = TIMEOUTRPC; 00334 00335 /* sanity checks. 00336 * note : file_attributes is optional. 00337 */ 00338 if(!filehandle || !p_context || !file_descriptor) 00339 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); 00340 00341 PRINT_HANDLE("FSAL_open_stateless", filehandle); 00342 00343 if(((proxyfsal_handle_t *)filehandle)->data.object_type_reminder != FSAL_TYPE_FILE) 00344 { 00345 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open); 00346 } 00347 00348 /* Setup results structures */ 00349 argnfs4.argarray.argarray_val = argoparray; 00350 resnfs4.resarray.resarray_val = resoparray; 00351 argnfs4.minorversion = 0; 00352 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */ 00353 argnfs4.tag.utf8string_val = NULL; 00354 argnfs4.tag.utf8string_len = 0; 00355 argnfs4.argarray.argarray_len = 0; 00356 00357 fsal_internal_proxy_setup_fattr(&fattr_internal); 00358 00359 /* Get NFSv4 File handle */ 00360 if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE) 00361 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); 00362 00363 bitmap.bitmap4_val = bitmap_open; 00364 bitmap.bitmap4_len = 2; 00365 fsal_internal_proxy_create_fattr_bitmap(&bitmap); 00366 00367 #define FSAL_OPEN_STATELESS_IDX_OP_PUTFH 0 00368 #define FSAL_OPEN_STATELESS_IDX_OP_GETATTR 1 00369 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00370 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); 00371 00372 resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. 00373 opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = 00374 bitmap_getattr_res; 00375 resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. 00376 opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 00377 00378 resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. 00379 opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 00380 (char *)&fattr_internal; 00381 resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. 00382 opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 00383 sizeof(fattr_internal); 00384 00385 TakeTokenFSCall(); 00386 00387 /* Call the NFSv4 function */ 00388 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 00389 if(rc != RPC_SUCCESS) 00390 { 00391 ReleaseTokenFSCall(); 00392 Return(ERR_FSAL_IO, rc, INDEX_FSAL_open); 00393 } 00394 00395 ReleaseTokenFSCall(); 00396 00397 /* >> convert error code, and return on error << */ 00398 if(resnfs4.status != NFS4_OK) 00399 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open); 00400 00401 /* Use NFSv4 service function to build the FSAL_attr */ 00402 if(file_attributes) 00403 { 00404 if(nfs4_Fattr_To_FSAL_attr(&attributes, 00405 &resnfs4.resarray.resarray_val 00406 [FSAL_OPEN_STATELESS_IDX_OP_GETATTR]. 00407 nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. 00408 obj_attributes) != NFS4_OK) 00409 { 00410 FSAL_CLEAR_MASK(file_attributes->asked_attributes); 00411 FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00412 00413 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open); 00414 } 00415 00416 memcpy(file_attributes, &attributes, sizeof(attributes)); 00417 } 00418 00419 /* >> fill output struct << */ 00420 memcpy((char *)&file_descriptor->fhandle, filehandle, sizeof(proxyfsal_handle_t)); 00421 file_descriptor->openflags = openflags; 00422 file_descriptor->current_offset = 0; 00423 file_descriptor->pcontext = p_context; 00424 00425 /* Keep the returned stateid for later use */ 00426 file_descriptor->stateid.seqid = 0; 00427 memset((char *)file_descriptor->stateid.other, 0, 12); 00428 00429 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open); 00430 } /* FSAL_open */ 00431 00460 fsal_status_t PROXYFSAL_read(fsal_file_t * file_desc, /* IN */ 00461 fsal_seek_t * seek_descriptor, /* IN */ 00462 fsal_size_t buffer_size, /* IN */ 00463 caddr_t buffer, /* OUT */ 00464 fsal_size_t * read_amount, /* OUT */ 00465 fsal_boolean_t * end_of_file /* OUT */ 00466 ) 00467 { 00468 int rc; 00469 COMPOUND4args argnfs4; 00470 COMPOUND4res resnfs4; 00471 nfs_fh4 nfs4fh; 00472 fsal_off_t offset; 00473 struct timeval timeout = TIMEOUTRPC; 00474 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00475 00476 #define FSAL_READ_NB_OP_ALLOC 2 00477 00478 nfs_argop4 argoparray[FSAL_READ_NB_OP_ALLOC]; 00479 nfs_resop4 resoparray[FSAL_READ_NB_OP_ALLOC]; 00480 00481 /* sanity checks. */ 00482 00483 if(!file_descriptor || !buffer || !read_amount || !end_of_file) 00484 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00485 00486 if(seek_descriptor == NULL) 00487 offset = file_descriptor->current_offset; 00488 else 00489 { 00490 switch (seek_descriptor->whence) 00491 { 00492 case FSAL_SEEK_SET: 00493 offset = seek_descriptor->offset; 00494 break; 00495 00496 case FSAL_SEEK_CUR: 00497 offset = seek_descriptor->offset + file_descriptor->current_offset; 00498 break; 00499 00500 default: 00501 case FSAL_SEEK_END: 00502 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_read); 00503 break; 00504 } 00505 } 00506 00507 /* Setup results structures */ 00508 argnfs4.argarray.argarray_val = argoparray; 00509 resnfs4.resarray.resarray_val = resoparray; 00510 argnfs4.minorversion = 0; 00511 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Read" ; */ 00512 argnfs4.tag.utf8string_val = NULL; 00513 argnfs4.tag.utf8string_len = 0; 00514 argnfs4.argarray.argarray_len = 0; 00515 00516 /* Get NFSv4 File handle */ 00517 if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &(file_descriptor->fhandle)) == FALSE) 00518 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00519 00520 #define FSAL_READ_IDX_OP_PUTFH 0 00521 #define FSAL_READ_IDX_OP_READ 1 00522 00523 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00524 COMPOUNDV4_ARG_ADD_OP_READ(argnfs4, &(file_descriptor->stateid), offset, buffer_size); 00525 00526 resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u. 00527 resok4.data.data_val = buffer; 00528 00529 TakeTokenFSCall(); 00530 00531 /* Call the NFSv4 function */ 00532 COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc); 00533 if(rc != RPC_SUCCESS) 00534 { 00535 ReleaseTokenFSCall(); 00536 00537 Return(ERR_FSAL_IO, rc, INDEX_FSAL_read); 00538 } 00539 00540 ReleaseTokenFSCall(); 00541 00542 /* >> convert error code, and return on error << */ 00543 if(resnfs4.status != NFS4_OK) 00544 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_read); 00545 00546 /* >> dont forget setting output vars : read_amount, end_of_file << */ 00547 *end_of_file = 00548 resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u. 00549 resok4.eof; 00550 *read_amount = 00551 resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u. 00552 resok4.data.data_len; 00553 00554 /* update the offset within the fsal_fd_t */ 00555 file_descriptor->current_offset += 00556 resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u. 00557 resok4.data.data_len; 00558 00559 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); 00560 00561 } /* FSAL_read */ 00562 00590 fsal_status_t PROXYFSAL_write(fsal_file_t * file_desc, /* IN */ 00591 fsal_op_context_t * p_context, /* IN */ 00592 fsal_seek_t * seek_descriptor, /* IN */ 00593 fsal_size_t buffer_size, /* IN */ 00594 caddr_t buffer, /* IN */ 00595 fsal_size_t * write_amount /* OUT */ 00596 ) 00597 { 00598 int rc; 00599 COMPOUND4args argnfs4; 00600 COMPOUND4res resnfs4; 00601 nfs_fh4 nfs4fh; 00602 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00603 00604 fsal_off_t offset; 00605 00606 struct timeval timeout = TIMEOUTRPC; 00607 00608 #define FSAL_WRITE_NB_OP_ALLOC 2 00609 00610 nfs_argop4 argoparray[FSAL_WRITE_NB_OP_ALLOC]; 00611 nfs_resop4 resoparray[FSAL_WRITE_NB_OP_ALLOC]; 00612 00613 /* sanity checks. */ 00614 if(!file_descriptor || !buffer || !write_amount) 00615 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); 00616 00617 if(seek_descriptor == NULL) 00618 offset = file_descriptor->current_offset; 00619 else 00620 { 00621 switch (seek_descriptor->whence) 00622 { 00623 case FSAL_SEEK_SET: 00624 offset = seek_descriptor->offset; 00625 break; 00626 00627 case FSAL_SEEK_CUR: 00628 offset = seek_descriptor->offset + file_descriptor->current_offset; 00629 break; 00630 00631 default: 00632 case FSAL_SEEK_END: 00633 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_write); 00634 break; 00635 } 00636 } 00637 00638 /* Setup results structures */ 00639 argnfs4.argarray.argarray_val = argoparray; 00640 resnfs4.resarray.resarray_val = resoparray; 00641 argnfs4.minorversion = 0; 00642 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Write" ; */ 00643 argnfs4.tag.utf8string_val = NULL; 00644 argnfs4.tag.utf8string_len = 0; 00645 argnfs4.argarray.argarray_len = 0; 00646 00647 /* Get NFSv4 File handle */ 00648 if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &(file_descriptor->fhandle)) == FALSE) 00649 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); 00650 00651 #define FSAL_READ_IDX_OP_PUTFH 0 00652 #define FSAL_READ_IDX_OP_WRITE 1 00653 00654 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00655 COMPOUNDV4_ARG_ADD_OP_WRITE(argnfs4, &(file_descriptor->stateid), offset, buffer, 00656 buffer_size); 00657 00658 TakeTokenFSCall(); 00659 00660 /* Call the NFSv4 function */ 00661 COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc); 00662 if(rc != RPC_SUCCESS) 00663 { 00664 ReleaseTokenFSCall(); 00665 00666 Return(ERR_FSAL_IO, rc, INDEX_FSAL_write); 00667 } 00668 00669 ReleaseTokenFSCall(); 00670 00671 /* >> convert error code, and return on error << */ 00672 if(resnfs4.status != NFS4_OK) 00673 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_write); 00674 00675 /* Set write_amount */ 00676 *write_amount = 00677 (fsal_size_t) resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_WRITE].nfs_resop4_u. 00678 opwrite.WRITE4res_u.resok4.count; 00679 00680 /* update the offset within the fsal_fd_t */ 00681 file_descriptor->current_offset += 00682 resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_WRITE].nfs_resop4_u.opwrite. 00683 WRITE4res_u.resok4.count; 00684 00685 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); 00686 } /* FSAL_write */ 00687 00702 fsal_status_t PROXYFSAL_close(fsal_file_t * file_desc /* IN */ 00703 ) 00704 { 00705 #define FSAL_CLOSE_NB_OP_ALLOC 2 00706 int rc; 00707 COMPOUND4args argnfs4; 00708 COMPOUND4res resnfs4; 00709 nfs_argop4 argoparray[FSAL_CLOSE_NB_OP_ALLOC]; 00710 nfs_resop4 resoparray[FSAL_CLOSE_NB_OP_ALLOC]; 00711 struct timeval timeout = TIMEOUTRPC; 00712 char All_Zero[] = "\0\0\0\0\0\0\0\0\0\0\0\0"; /* 12 times \0 */ 00713 nfs_fh4 nfs4fh; 00714 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00715 00716 /* Setup results structures */ 00717 argnfs4.argarray.argarray_val = argoparray; 00718 resnfs4.resarray.resarray_val = resoparray; 00719 argnfs4.minorversion = 0; 00720 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */ 00721 argnfs4.tag.utf8string_val = NULL; 00722 argnfs4.tag.utf8string_len = 0; 00723 argnfs4.argarray.argarray_len = 0; 00724 00725 /* sanity checks. */ 00726 if(!file_descriptor) 00727 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close); 00728 00729 /* Check if this was a "stateless" open, then nothing is to be done at close */ 00730 if(!memcmp(file_descriptor->stateid.other, All_Zero, 12)) 00731 { 00732 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00733 } 00734 00735 /* Get NFSv4 File handle */ 00736 if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *)&(file_descriptor->fhandle)) == FALSE) 00737 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close); 00738 00739 #define FSAL_CLOSE_IDX_OP_PUTFH 0 00740 #define FSAL_CLOSE_IDX_OP_CLOSE 1 00741 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00742 COMPOUNDV4_ARG_ADD_OP_CLOSE(argnfs4, file_descriptor->stateid); 00743 00744 TakeTokenFSCall(); 00745 00746 /* Call the NFSv4 function */ 00747 COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc); 00748 if(rc != RPC_SUCCESS) 00749 { 00750 ReleaseTokenFSCall(); 00751 00752 Return(ERR_FSAL_IO, rc, INDEX_FSAL_close); 00753 } 00754 00755 ReleaseTokenFSCall(); 00756 00757 /* >> convert error code, and return on error << */ 00758 if(resnfs4.status != NFS4_OK) 00759 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_close); 00760 00761 /* Update fd structure */ 00762 file_descriptor->stateid.seqid += 1; 00763 00764 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00765 } /* FSAL_close */ 00766 00781 fsal_status_t PROXYFSAL_close_by_fileid(fsal_file_t * file_desc /* IN */ , 00782 fsal_u64_t fileid) 00783 #ifndef _USE_PROXY 00784 { 00785 return ERR_FSAL_NOTSUPP; 00786 } 00787 #else 00788 { 00789 int rc; 00790 COMPOUND4args argnfs4; 00791 COMPOUND4res resnfs4; 00792 nfs_fh4 nfs4fh_hldir; 00793 component4 name; 00794 char nameval[MAXNAMLEN]; 00795 char filename[MAXNAMLEN]; 00796 fsal_status_t fsal_status; 00797 struct timeval timeout = TIMEOUTRPC; 00798 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00799 00800 #define FSAL_CLOSE_BY_FILEID_NB_OP 4 00801 00802 nfs_argop4 argoparray[FSAL_CLOSE_BY_FILEID_NB_OP]; 00803 nfs_resop4 resoparray[FSAL_CLOSE_BY_FILEID_NB_OP]; 00804 00805 /* sanity checks. */ 00806 if(!file_descriptor) 00807 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid); 00808 00809 /* Setup results structures */ 00810 argnfs4.argarray.argarray_val = argoparray; 00811 resnfs4.resarray.resarray_val = resoparray; 00812 argnfs4.minorversion = 0; 00813 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Write" ; */ 00814 argnfs4.tag.utf8string_val = NULL; 00815 argnfs4.tag.utf8string_len = 0; 00816 argnfs4.argarray.argarray_len = 0; 00817 00818 /* Get NFSv4 File handle */ 00819 00820 if(fsal_internal_proxy_extract_fh 00821 (&nfs4fh_hldir, (fsal_handle_t *) &(file_descriptor->pcontext->openfh_wd_handle)) == FALSE) 00822 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid); 00823 00824 snprintf(filename, MAXNAMLEN, ".ganesha.open_by_fid.%llu", fileid); 00825 name.utf8string_val = nameval; 00826 00827 if(str2utf8(filename, &name) == -1) 00828 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid); 00829 00830 #define FSAL_CLOSE_BY_FILEID_IDX_OP_PUTFH 0 00831 #define FSAL_CLOSE_BY_FILEID_IDX_OP_REMOVE 1 00832 00833 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_hldir); 00834 COMPOUNDV4_ARG_ADD_OP_REMOVE(argnfs4, name); 00835 00836 TakeTokenFSCall(); 00837 00838 /* Call the NFSv4 function */ 00839 COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc); 00840 if(rc != RPC_SUCCESS) 00841 { 00842 ReleaseTokenFSCall(); 00843 00844 Return(ERR_FSAL_IO, rc, INDEX_FSAL_close_by_fileid); 00845 } 00846 00847 ReleaseTokenFSCall(); 00848 00849 fsal_status = FSAL_close((fsal_file_t *)file_descriptor); 00850 00851 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_close_by_fileid); 00852 } 00853 #endif 00854 00893 fsal_status_t PROXYFSAL_open_by_fileid(fsal_handle_t * filehandle, /* IN */ 00894 fsal_u64_t fileid, /* IN */ 00895 fsal_op_context_t *context, /* IN */ 00896 fsal_openflags_t openflags, /* IN */ 00897 fsal_file_t * file_desc, /* OUT */ 00898 fsal_attrib_list_t * 00899 file_attributes /* [ IN/OUT ] */ ) 00900 #ifndef _USE_PROXY 00901 { 00902 return ERR_FSAL_NOTSUPP; 00903 } 00904 #else 00905 { 00906 int rc; 00907 COMPOUND4args argnfs4; 00908 COMPOUND4res resnfs4; 00909 nfs_fh4 nfs4fh; 00910 nfs_fh4 nfs4fh_hldir; 00911 bitmap4 bitmap; 00912 uint32_t bitmap_res[2]; 00913 uint32_t bitmap_open[2]; 00914 uint32_t bitmap_getattr_res[2]; 00915 uint32_t share_access; 00916 component4 name; 00917 char nameval[MAXNAMLEN]; 00918 char filename[MAXNAMLEN]; 00919 fsal_status_t fsal_status; 00920 proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc; 00921 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00922 00923 #define FSAL_OPEN_BY_FILEID_NB_OP_ALLOC 7 00924 #define FSAL_OPEN_VAL_BUFFER 1024 00925 00926 fsal_proxy_internal_fattr_t fattr_internal; 00927 fsal_attrib_list_t attributes; 00928 nfs_argop4 argoparray[FSAL_OPEN_BY_FILEID_NB_OP_ALLOC]; 00929 nfs_resop4 resoparray[FSAL_OPEN_BY_FILEID_NB_OP_ALLOC]; 00930 char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; 00931 struct timeval timeout = TIMEOUTRPC; 00932 char owner_val[FSAL_PROXY_OWNER_LEN]; 00933 unsigned int owner_len = 0; 00934 00935 /* sanity checks. 00936 * note : file_attributes is optional. 00937 */ 00938 if(!filehandle || !p_context || !file_descriptor) 00939 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid); 00940 00941 PRINT_HANDLE("FSAL_open_by_fileid", filehandle); 00942 00943 if(((proxyfsal_handle_t *)filehandle)->data.object_type_reminder != FSAL_TYPE_FILE) 00944 { 00945 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_fileid); 00946 } 00947 00948 /* Create the owner */ 00949 snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu", 00950 getpid(), p_context, (unsigned long long int)((proxyfsal_op_context_t *)p_context)->file_counter); 00951 owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN); 00952 ((proxyfsal_op_context_t *)p_context)->file_counter += 1; 00953 00954 /* Setup results structures */ 00955 argnfs4.argarray.argarray_val = argoparray; 00956 resnfs4.resarray.resarray_val = resoparray; 00957 argnfs4.minorversion = 0; 00958 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */ 00959 argnfs4.tag.utf8string_val = NULL; 00960 argnfs4.tag.utf8string_len = 0; 00961 argnfs4.argarray.argarray_len = 0; 00962 00963 fsal_internal_proxy_setup_fattr(&fattr_internal); 00964 00965 snprintf(filename, MAXNAMLEN, ".ganesha.open_by_fid.%llu", fileid); 00966 name.utf8string_val = nameval; 00967 00968 if(str2utf8(filename, &name) == -1) 00969 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid); 00970 00971 /* Get NFSv4 File handle */ 00972 if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE) 00973 { 00974 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid); 00975 } 00976 00977 if(fsal_internal_proxy_extract_fh(&nfs4fh_hldir, (fsal_handle_t *) &(p_context->openfh_wd_handle)) == 00978 FALSE) 00979 { 00980 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid); 00981 } 00982 bitmap.bitmap4_val = bitmap_open; 00983 bitmap.bitmap4_len = 2; 00984 fsal_internal_proxy_create_fattr_bitmap(&bitmap); 00985 00986 share_access = 0; 00987 if((openflags & FSAL_O_RDWR) == FSAL_O_RDWR) 00988 share_access |= OPEN4_SHARE_ACCESS_BOTH; 00989 00990 if((openflags & FSAL_O_RDONLY) == FSAL_O_RDONLY) 00991 share_access |= OPEN4_SHARE_ACCESS_READ; 00992 00993 if(((openflags & FSAL_O_WRONLY) == FSAL_O_WRONLY) || 00994 ((openflags & FSAL_O_APPEND) == FSAL_O_APPEND)) 00995 share_access |= OPEN4_SHARE_ACCESS_WRITE; 00996 00997 /* >> you can check if this is a file if the information 00998 * is stored into the handle << */ 00999 #define FSAL_OPEN_BYFID_IDX_OP_PUTFH 0 01000 #define FSAL_OPEN_BYFID_IDX_OP_SAVEFH 1 01001 #define FSAL_OPEN_BYFID_IDX_OP_PUTFH_HLDIR 2 01002 #define FSAL_OPEN_BYFID_IDX_OP_LINK 3 01003 #define FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE 4 01004 #define FSAL_OPEN_BYFID_IDX_OP_GETFH 5 01005 #define FSAL_OPEN_BYFID_IDX_OP_GETATTR 6 01006 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 01007 COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4); 01008 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_hldir); 01009 COMPOUNDV4_ARG_ADD_OP_LINK(argnfs4, name); 01010 COMPOUNDV4_ARG_ADD_OP_OPEN_NOCREATE(argnfs4, file_descriptor->stateid.seqid, 01011 p_context->clientid, share_access, name, owner_val, 01012 owner_len); 01013 COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); 01014 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); 01015 01016 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 01017 OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res; 01018 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 01019 OPEN4res_u.resok4.attrset.bitmap4_len = 2; 01020 01021 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 01022 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res; 01023 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 01024 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 01025 01026 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 01027 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 01028 (char *)&fattr_internal; 01029 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 01030 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 01031 sizeof(fattr_internal); 01032 01033 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 01034 GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; 01035 resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 01036 GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; 01037 01038 TakeTokenFSCall(); 01039 01040 /* Call the NFSv4 function */ 01041 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 01042 if(rc != RPC_SUCCESS) 01043 { 01044 ReleaseTokenFSCall(); 01045 01046 Return(ERR_FSAL_IO, rc, INDEX_FSAL_open_by_fileid); 01047 } 01048 01049 ReleaseTokenFSCall(); 01050 01051 /* >> convert error code, and return on error << */ 01052 if(resnfs4.status != NFS4_OK) 01053 { 01054 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open_by_fileid); 01055 } 01056 01057 /* Use NFSv4 service function to build the FSAL_attr */ 01058 if(nfs4_Fattr_To_FSAL_attr(&attributes, 01059 &resnfs4.resarray. 01060 resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u. 01061 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) 01062 { 01063 FSAL_CLEAR_MASK(file_attributes->asked_attributes); 01064 FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 01065 01066 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_fileid); 01067 } 01068 01069 if(file_attributes) 01070 { 01071 memcpy(file_attributes, &attributes, sizeof(attributes)); 01072 } 01073 01074 /* Keep the returned stateid for later use */ 01075 file_descriptor->stateid.seqid = 01076 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen. 01077 OPEN4res_u.resok4.stateid.seqid; 01078 memcpy((char *)file_descriptor->stateid.other, 01079 resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u. 01080 opopen.OPEN4res_u.resok4.stateid.other, 12); 01081 01082 /* >> fill output struct << */ 01083 /* Build the handle */ 01084 if(fsal_internal_proxy_create_fh 01085 (&resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 01086 GETFH4res_u.resok4.object, FSAL_TYPE_FILE, attributes.fileid, 01087 (fsal_handle_t *) &file_descriptor->fhandle) == FALSE) 01088 { 01089 gsh_free(name.utf8string_val); 01090 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid); 01091 } 01092 01093 file_descriptor->openflags = openflags; 01094 file_descriptor->current_offset = 0; 01095 file_descriptor->pcontext = p_context; 01096 01097 /* See if a OPEN_CONFIRM is required */ 01098 if(resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u. 01099 opopen.OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM) 01100 { 01101 fsal_status = FSAL_proxy_open_confirm(file_descriptor); 01102 if(FSAL_IS_ERROR(fsal_status)) 01103 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_open); 01104 } 01105 01106 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open_by_fileid); 01107 01108 } /* FSAL_open_by_fileid */ 01109 #endif 01110 01111 unsigned int PROXYFSAL_GetFileno(fsal_file_t * pfile) 01112 { 01113 unsigned int intpfile; 01114 01115 memcpy((char *)&intpfile, pfile, sizeof(unsigned int)); 01116 return intpfile; 01117 } 01118 01119 01137 fsal_status_t PROXYFSAL_commit( fsal_file_t * p_file_descriptor, 01138 fsal_off_t offset, 01139 fsal_size_t length ) 01140 { 01141 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); 01142 }