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 #include "fsal.h" 00018 #include "fsal_internal.h" 00019 #include "fsal_convert.h" 00020 00060 fsal_status_t POSIXFSAL_open_by_name(fsal_handle_t * dirhandle, /* IN */ 00061 fsal_name_t * filename, /* IN */ 00062 fsal_op_context_t * p_context, /* IN */ 00063 fsal_openflags_t openflags, /* IN */ 00064 fsal_file_t * file_descriptor, /* OUT */ 00065 fsal_attrib_list_t * 00066 file_attributes /* [ IN/OUT ] */ ) 00067 { 00068 fsal_status_t fsal_status; 00069 posixfsal_handle_t filehandle; 00070 00071 if(!dirhandle || !filename || !p_context || !file_descriptor) 00072 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00073 00074 fsal_status = 00075 POSIXFSAL_lookup(dirhandle, filename, p_context, 00076 (fsal_handle_t *)&filehandle, file_attributes); 00077 if(FSAL_IS_ERROR(fsal_status)) 00078 return fsal_status; 00079 00080 return POSIXFSAL_open((fsal_handle_t *)&filehandle, p_context, 00081 openflags, file_descriptor, 00082 file_attributes); 00083 } 00084 00115 fsal_status_t POSIXFSAL_open(fsal_handle_t * filehandle, /* IN */ 00116 fsal_op_context_t * context, /* IN */ 00117 fsal_openflags_t openflags, /* IN */ 00118 fsal_file_t * file_descriptor, /* OUT */ 00119 fsal_attrib_list_t * p_file_attributes /* [ IN/OUT ] */ 00120 ) 00121 { 00122 posixfsal_handle_t * p_filehandle = (posixfsal_handle_t *) filehandle; 00123 posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context; 00124 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00125 int rc, errsv; 00126 fsal_status_t status; 00127 00128 fsal_path_t fsalpath; 00129 struct stat buffstat; 00130 #ifdef _FSAL_POSIX_USE_STREAM 00131 char posix_flags[4]; /* stores r, r+, w, w+, a, or a+ */ 00132 #else 00133 int posix_flags; 00134 #endif 00135 00136 /* sanity checks. 00137 * note : file_attributes is optional. 00138 */ 00139 if(!p_filehandle || !p_context || !p_file_descriptor) 00140 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); 00141 00142 status = 00143 fsal_internal_getPathFromHandle(p_context, p_filehandle, 0, &fsalpath, &buffstat); 00144 if(FSAL_IS_ERROR(status)) 00145 Return(status.major, status.minor, INDEX_FSAL_open); 00146 00147 status = 00148 fsal_internal_testAccess(p_context, 00149 (openflags & FSAL_O_RDONLY ? FSAL_R_OK : FSAL_W_OK) | 00150 FSAL_OWNER_OK, &buffstat, NULL); 00151 if(FSAL_IS_ERROR(status)) 00152 Return(status.major, status.minor, INDEX_FSAL_open); 00153 00154 /* convert fsal open flags to posix open flags */ 00155 rc = fsal2posix_openflags(openflags, &posix_flags); 00156 00157 /* flags conflicts. */ 00158 if(rc) 00159 { 00160 LogEvent(COMPONENT_FSAL, "Invalid/conflicting flags : %#X", openflags); 00161 Return(rc, 0, INDEX_FSAL_open); 00162 } 00163 00164 TakeTokenFSCall(); 00165 #ifdef _FSAL_POSIX_USE_STREAM 00166 p_file_descriptor->p_file = fopen(fsalpath.path, posix_flags); 00167 errsv = errno; 00168 ReleaseTokenFSCall(); 00169 00170 if(!(p_file_descriptor->p_file)) 00171 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_open); 00172 #else 00173 p_file_descriptor->filefd = open(fsalpath.path, posix_flags); 00174 errsv = errno; 00175 ReleaseTokenFSCall(); 00176 #endif 00177 00178 /* set the read-only flag of the file descriptor */ 00179 p_file_descriptor->ro = openflags & FSAL_O_RDONLY; 00180 00181 /* output attributes */ 00182 if(p_file_attributes) 00183 { 00184 00185 status = posix2fsal_attributes(&buffstat, p_file_attributes); 00186 00187 if(FSAL_IS_ERROR(status)) 00188 { 00189 FSAL_CLEAR_MASK(p_file_attributes->asked_attributes); 00190 FSAL_SET_MASK(p_file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00191 } 00192 } 00193 00194 Return(ERR_FSAL_NO_ERROR, errsv, INDEX_FSAL_open); /* use the error... */ 00195 00196 } 00197 00222 #ifdef _FSAL_POSIX_USE_STREAM 00223 fsal_status_t POSIXFSAL_read(fsal_file_t * file_descriptor, /* IN */ 00224 fsal_seek_t * p_seek_descriptor, /* [IN] */ 00225 fsal_size_t buffer_size, /* IN */ 00226 caddr_t buffer, /* OUT */ 00227 fsal_size_t * p_read_amount, /* OUT */ 00228 fsal_boolean_t * p_end_of_file /* OUT */ 00229 ) 00230 { 00231 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00232 size_t i_size; 00233 size_t nb_read; 00234 int rc, errsv; 00235 00236 /* sanity checks. */ 00237 00238 if(!p_file_descriptor || !buffer || !p_read_amount || !p_end_of_file) 00239 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00240 00242 i_size = (size_t) buffer_size; 00243 00244 /* positioning */ 00245 00246 if(p_seek_descriptor) 00247 { 00248 00249 switch (p_seek_descriptor->whence) 00250 { 00251 case FSAL_SEEK_CUR: 00252 /* set position plus offset */ 00253 00254 TakeTokenFSCall(); 00255 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_CUR); 00256 errsv = errno; 00257 ReleaseTokenFSCall(); 00258 break; 00259 00260 case FSAL_SEEK_SET: 00261 /* set absolute position to offset */ 00262 00263 TakeTokenFSCall(); 00264 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_SET); 00265 errsv = errno; 00266 ReleaseTokenFSCall(); 00267 00268 break; 00269 00270 case FSAL_SEEK_END: 00271 /* set end of file plus offset */ 00272 00273 TakeTokenFSCall(); 00274 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_END); 00275 errsv = errno; 00276 ReleaseTokenFSCall(); 00277 00278 break; 00279 } 00280 00281 if(rc) 00282 { 00283 00284 LogEvent(COMPONENT_FSAL, 00285 "Error in posix fseek operation (whence=%s, offset=%lld)", 00286 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00287 (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : 00288 (p_seek_descriptor->whence == 00289 FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), 00290 p_seek_descriptor->offset); 00291 00292 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_read); 00293 } 00294 00295 } 00296 00297 /* read operation */ 00298 00299 TakeTokenFSCall(); 00300 00301 nb_read = fread(buffer, 1, i_size, p_file_descriptor->p_file); 00302 00303 ReleaseTokenFSCall(); 00304 00307 if(feof(p_file_descriptor->p_file)) 00308 *p_end_of_file = 1; 00309 00310 if(nb_read == 0 && ferror(p_file_descriptor->p_file)) 00311 { 00312 Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_read); 00313 } 00314 00315 *p_read_amount = nb_read; 00316 00317 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); 00318 00319 } 00320 #else 00321 fsal_status_t POSIXFSAL_read(fsal_file_t * file_descriptor, /* IN */ 00322 fsal_seek_t * p_seek_descriptor, /* [IN] */ 00323 fsal_size_t buffer_size, /* IN */ 00324 caddr_t buffer, /* OUT */ 00325 fsal_size_t * p_read_amount, /* OUT */ 00326 fsal_boolean_t * p_end_of_file /* OUT */ 00327 ) 00328 { 00329 00330 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00331 size_t i_size; 00332 size_t nb_read; 00333 int rc, errsv; 00334 char c; 00335 00336 /* sanity checks. */ 00337 if(!p_file_descriptor || !buffer || !p_read_amount || !p_end_of_file) 00338 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00339 00341 i_size = (size_t) buffer_size; 00342 00343 /* positioning */ 00344 00345 if(p_seek_descriptor) 00346 { 00347 00348 switch (p_seek_descriptor->whence) 00349 { 00350 case FSAL_SEEK_CUR: 00351 case FSAL_SEEK_END: 00352 /* set position plus offset */ 00353 00354 TakeTokenFSCall(); 00355 rc = lseek(p_file_descriptor->filefd, p_seek_descriptor->offset, 00356 p_seek_descriptor->whence); 00357 errsv = errno; 00358 00359 if(rc) 00360 { 00361 LogEvent(COMPONENT_FSAL, 00362 "Error in posix fseek operation (whence=%s, offset=%"PRId64")", 00363 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00364 (p_seek_descriptor->whence == 00365 FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence 00366 == 00367 FSAL_SEEK_END ? "SEEK_END" 00368 : "ERROR"))), 00369 p_seek_descriptor->offset); 00370 00371 ReleaseTokenFSCall(); 00372 00373 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_read); 00374 } 00375 00376 nb_read = read(p_file_descriptor->filefd, buffer, i_size); 00377 00378 ReleaseTokenFSCall(); 00379 break; 00380 00381 case FSAL_SEEK_SET: 00382 /* set absolute position to offset */ 00383 00384 TakeTokenFSCall(); 00385 nb_read = 00386 pread(p_file_descriptor->filefd, buffer, i_size, p_seek_descriptor->offset); 00387 errsv = errno; 00388 00389 rc = pread(p_file_descriptor->filefd, &c, 1, 00390 p_seek_descriptor->offset + i_size); 00391 if(rc == 0) 00392 *p_end_of_file = 1; 00393 00394 ReleaseTokenFSCall(); 00395 00396 break; 00397 } 00398 } 00399 else 00400 { 00401 TakeTokenFSCall(); 00402 00403 nb_read = read(p_file_descriptor->filefd, buffer, i_size); 00404 00405 ReleaseTokenFSCall(); 00406 } 00407 00409 if(nb_read == -1) 00410 Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_read); 00411 00412 if(nb_read == 0 && i_size != 0) 00413 *p_end_of_file = 1; 00414 00415 *p_read_amount = nb_read; 00416 00417 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); 00418 00419 } 00420 #endif /* _FSAL_POSIX_USE_STREAM */ 00421 00445 #ifdef _FSAL_POSIX_USE_STREAM 00446 fsal_status_t POSIXFSAL_write(fsal_file_t * file_descriptor, /* IN */ 00447 fsal_op_context_t * p_context, /* IN */ 00448 fsal_seek_t * p_seek_descriptor, /* IN */ 00449 fsal_size_t buffer_size, /* IN */ 00450 caddr_t buffer, /* IN */ 00451 fsal_size_t * p_write_amount /* OUT */ 00452 ) 00453 { 00454 00455 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00456 size_t nb_written; 00457 size_t i_size; 00458 int rc, errsv; 00459 00460 /* sanity checks. */ 00461 if(!p_file_descriptor || !buffer || !p_write_amount) 00462 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); 00463 00464 if(p_file_descriptor->ro) 00465 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_write); 00466 00468 i_size = (size_t) buffer_size; 00469 00470 /* positioning */ 00471 00472 if(p_seek_descriptor) 00473 { 00474 00475 switch (p_seek_descriptor->whence) 00476 { 00477 case FSAL_SEEK_CUR: 00478 /* set position plus offset */ 00479 00480 TakeTokenFSCall(); 00481 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_CUR); 00482 errsv = errno; 00483 ReleaseTokenFSCall(); 00484 break; 00485 00486 case FSAL_SEEK_SET: 00487 /* set absolute position to offset */ 00488 00489 TakeTokenFSCall(); 00490 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_SET); 00491 errsv = errno; 00492 ReleaseTokenFSCall(); 00493 00494 break; 00495 00496 case FSAL_SEEK_END: 00497 /* set end of file plus offset */ 00498 00499 TakeTokenFSCall(); 00500 rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_END); 00501 errsv = errno; 00502 ReleaseTokenFSCall(); 00503 00504 break; 00505 } 00506 00507 if(rc) 00508 { 00509 00510 LogEvent(COMPONENT_FSAL, 00511 "Error in posix fseek operation (whence=%s, offset=%lld)", 00512 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00513 (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : 00514 (p_seek_descriptor->whence == 00515 FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), 00516 p_seek_descriptor->offset); 00517 00518 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); 00519 00520 } 00521 00522 LogFullDebug(COMPONENT_FSAL, 00523 "Write operation (whence=%s, offset=%lld, size=%lld)", 00524 (p_seek_descriptor->whence == 00525 FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == 00526 FSAL_SEEK_SET ? "SEEK_SET" 00527 : (p_seek_descriptor->whence == 00528 FSAL_SEEK_END ? "SEEK_END" : 00529 "ERROR"))), 00530 p_seek_descriptor->offset, buffer_size); 00531 00532 } 00533 00534 /* write operation */ 00535 00536 TakeTokenFSCall(); 00537 00538 nb_written = fwrite(buffer, 1, i_size, p_file_descriptor->p_file); 00539 00540 /* With no flush, uncommited write may occur on 64 bits platforms */ 00541 (void)fflush(p_file_descriptor->p_file); 00542 00543 ReleaseTokenFSCall(); 00544 00547 if(nb_written <= 0 && ferror(p_file_descriptor->p_file)) 00548 { 00549 Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_write); 00550 } 00551 00552 /* set output vars */ 00553 00554 *p_write_amount = (fsal_size_t) nb_written; 00555 00556 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); 00557 00558 } 00559 #else 00560 fsal_status_t POSIXFSAL_write(fsal_file_t * file_descriptor, /* IN */ 00561 fsal_op_context_t * p_context, /* IN */ 00562 fsal_seek_t * p_seek_descriptor, /* IN */ 00563 fsal_size_t buffer_size, /* IN */ 00564 caddr_t buffer, /* IN */ 00565 fsal_size_t * p_write_amount /* OUT */ 00566 ) 00567 { 00568 00569 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00570 size_t i_size; 00571 size_t nb_written; 00572 int rc, errsv; 00573 00574 /* sanity checks. */ 00575 if(!p_file_descriptor || !buffer || !p_write_amount) 00576 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00577 00579 i_size = (size_t) buffer_size; 00580 00581 /* positioning */ 00582 00583 if(p_seek_descriptor) 00584 { 00585 00586 switch (p_seek_descriptor->whence) 00587 { 00588 case FSAL_SEEK_CUR: 00589 case FSAL_SEEK_END: 00590 /* set position plus offset */ 00591 00592 TakeTokenFSCall(); 00593 rc = lseek(p_file_descriptor->filefd, p_seek_descriptor->offset, 00594 p_seek_descriptor->whence); 00595 errsv = errno; 00596 00597 if(rc) 00598 { 00599 LogEvent(COMPONENT_FSAL, 00600 "Error in posix fseek operation (whence=%s, offset=%"PRId64")", 00601 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00602 (p_seek_descriptor->whence == 00603 FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence 00604 == 00605 FSAL_SEEK_END ? "SEEK_END" 00606 : "ERROR"))), 00607 p_seek_descriptor->offset); 00608 00609 ReleaseTokenFSCall(); 00610 00611 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); 00612 } 00613 00614 nb_written = write(p_file_descriptor->filefd, buffer, i_size); 00615 00616 ReleaseTokenFSCall(); 00617 break; 00618 00619 case FSAL_SEEK_SET: 00620 /* set absolute position to offset */ 00621 00622 TakeTokenFSCall(); 00623 nb_written = 00624 pwrite(p_file_descriptor->filefd, buffer, i_size, 00625 p_seek_descriptor->offset); 00626 errsv = errno; 00627 00628 ReleaseTokenFSCall(); 00629 00630 break; 00631 } 00632 } 00633 else 00634 { 00635 TakeTokenFSCall(); 00636 00637 nb_written = write(p_file_descriptor->filefd, buffer, i_size); 00638 00639 ReleaseTokenFSCall(); 00640 } 00641 00643 if(nb_written == -1) 00644 Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_write); 00645 00646 *p_write_amount = nb_written; 00647 00648 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); 00649 00650 } 00651 00652 #endif /* _FSAL_POSIX_USE_STREAM */ 00653 00666 fsal_status_t POSIXFSAL_close(fsal_file_t * file_descriptor /* IN */ 00667 ) 00668 { 00669 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00670 int rc, errsv; 00671 00672 /* sanity checks. */ 00673 if(!p_file_descriptor) 00674 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close); 00675 00676 /* call to close */ 00677 00678 TakeTokenFSCall(); 00679 00680 #ifdef _FSAL_POSIX_USE_STREAM 00681 rc = fclose(p_file_descriptor->p_file); 00682 #else 00683 rc = close(p_file_descriptor->filefd); 00684 #endif 00685 00686 errsv = errno; 00687 00688 ReleaseTokenFSCall(); 00689 00690 if(rc) 00691 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_close); 00692 00693 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00694 00695 } 00696 00697 unsigned int POSIXFSAL_GetFileno(fsal_file_t * pfile) 00698 { 00699 return ((posixfsal_file_t *)pfile)->filefd; 00700 } 00701 00719 fsal_status_t POSIXFSAL_commit(fsal_file_t * file_descriptor, 00720 fsal_off_t offset, 00721 fsal_size_t length ) 00722 00723 { 00724 posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor; 00725 int rc, errsv; 00726 00727 /* sanity checks. */ 00728 if(!p_file_descriptor) 00729 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_commit); 00730 00731 /* Flush data. */ 00732 TakeTokenFSCall(); 00733 rc = fsync(p_file_descriptor->filefd); 00734 errsv = errno; 00735 ReleaseTokenFSCall(); 00736 00737 if(rc) 00738 { 00739 LogEvent(COMPONENT_FSAL, "Error in fsync operation"); 00740 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_commit); 00741 } 00742 00743 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); 00744 }