nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * ------------- 00024 */ 00025 00034 #ifdef HAVE_CONFIG_H 00035 #include "config.h" 00036 #endif 00037 00038 #include "fsal.h" 00039 #include "fsal_internal.h" 00040 #include "FSAL/access_check.h" 00041 #include "fsal_convert.h" 00042 00082 fsal_status_t XFSFSAL_open_by_name(fsal_handle_t * dirhandle, /* IN */ 00083 fsal_name_t * filename, /* IN */ 00084 fsal_op_context_t * p_context, /* IN */ 00085 fsal_openflags_t openflags, /* IN */ 00086 fsal_file_t * file_descriptor, /* OUT */ 00087 fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ ) 00088 { 00089 fsal_status_t fsal_status; 00090 xfsfsal_handle_t filehandle; 00091 00092 if(!dirhandle || !filename || !p_context || !file_descriptor) 00093 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00094 00095 fsal_status = 00096 XFSFSAL_lookup(dirhandle, filename, p_context, &filehandle, file_attributes); 00097 if(FSAL_IS_ERROR(fsal_status)) 00098 return fsal_status; 00099 00100 return XFSFSAL_open(&filehandle, p_context, openflags, file_descriptor, 00101 file_attributes); 00102 } 00103 00134 fsal_status_t XFSFSAL_open(fsal_handle_t * p_filehandle, /* IN */ 00135 fsal_op_context_t * p_context, /* IN */ 00136 fsal_openflags_t openflags, /* IN */ 00137 fsal_file_t * p_file_descriptor, /* OUT */ 00138 fsal_attrib_list_t * p_file_attributes /* [ IN/OUT ] */ 00139 ) 00140 { 00141 00142 int rc, errsv; 00143 fsal_status_t status; 00144 00145 int fd = 0 ; 00146 struct stat buffstat; 00147 int posix_flags = 0; 00148 00149 /* sanity checks. 00150 * note : file_attributes is optional. 00151 */ 00152 if(!p_filehandle || !p_context || !p_file_descriptor) 00153 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); 00154 00155 /* convert fsal open flags to posix open flags */ 00156 rc = fsal2posix_openflags(openflags, &posix_flags); 00157 00158 /* flags conflicts. */ 00159 if(rc) 00160 { 00161 LogEvent(COMPONENT_FSAL, "Invalid/conflicting flags : %#X", 00162 openflags); 00163 Return(rc, 0, INDEX_FSAL_open); 00164 } 00165 00166 TakeTokenFSCall(); 00167 status = fsal_internal_handle2fd(p_context, p_filehandle, &fd, posix_flags); 00168 ReleaseTokenFSCall(); 00169 00170 if(FSAL_IS_ERROR(status)) 00171 ReturnStatus(status, INDEX_FSAL_open); 00172 00173 /* retrieve file attributes for checking access rights */ 00174 00175 TakeTokenFSCall(); 00176 rc = fstat(fd, &buffstat); 00177 errsv = errno; 00178 ReleaseTokenFSCall(); 00179 00180 if(rc) 00181 { 00182 close(fd); 00183 00184 if(errsv == ENOENT) 00185 Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_open); 00186 else 00187 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_open); 00188 } 00189 00190 #if 0 00191 /* No required, the open would have failed if not permitted */ 00192 status = 00193 fsal_check_access(p_context, 00194 openflags & FSAL_O_RDONLY ? FSAL_R_OK : FSAL_W_OK, 00195 &buffstat, NULL); 00196 if(FSAL_IS_ERROR(status)) 00197 { 00198 close(fd); 00199 ReturnStatus(status, INDEX_FSAL_open); 00200 } 00201 #endif 00202 00203 TakeTokenFSCall(); 00204 ((xfsfsal_file_t *)p_file_descriptor)->fd = fd; 00205 errsv = errno; 00206 ReleaseTokenFSCall(); 00207 00208 /* set the read-only flag of the file descriptor */ 00209 ((xfsfsal_file_t *)p_file_descriptor)->ro = openflags & FSAL_O_RDONLY; 00210 00211 /* output attributes */ 00212 if(p_file_attributes) 00213 { 00214 00215 status = posix2fsal_attributes(&buffstat, p_file_attributes); 00216 00217 if(FSAL_IS_ERROR(status)) 00218 { 00219 FSAL_CLEAR_MASK(p_file_attributes->asked_attributes); 00220 FSAL_SET_MASK(p_file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00221 } 00222 } 00223 00224 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open); 00225 00226 } 00227 00252 fsal_status_t XFSFSAL_read(fsal_file_t * p_file_descriptor, /* IN */ 00253 fsal_seek_t * p_seek_descriptor, /* [IN] */ 00254 fsal_size_t buffer_size, /* IN */ 00255 caddr_t buffer, /* OUT */ 00256 fsal_size_t * p_read_amount, /* OUT */ 00257 fsal_boolean_t * p_end_of_file /* OUT */ 00258 ) 00259 { 00260 00261 size_t i_size; 00262 ssize_t nb_read; 00263 int rc, errsv; 00264 int pcall = FALSE; 00265 00266 /* sanity checks. */ 00267 00268 if(!p_file_descriptor || !buffer || !p_read_amount || !p_end_of_file) 00269 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00270 00272 i_size = (size_t) buffer_size; 00273 00274 /* positioning */ 00275 00276 if(p_seek_descriptor) 00277 { 00278 00279 switch (p_seek_descriptor->whence) 00280 { 00281 case FSAL_SEEK_CUR: 00282 /* set position plus offset */ 00283 pcall = FALSE; 00284 TakeTokenFSCall(); 00285 rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, 00286 p_seek_descriptor->offset, SEEK_CUR); 00287 errsv = errno; 00288 ReleaseTokenFSCall(); 00289 break; 00290 00291 case FSAL_SEEK_SET: 00292 /* use pread/pwrite call */ 00293 pcall = TRUE; 00294 rc = 0; 00295 errsv = 0; 00296 break; 00297 00298 case FSAL_SEEK_END: 00299 /* set end of file plus offset */ 00300 pcall = FALSE; 00301 00302 TakeTokenFSCall(); 00303 rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, 00304 p_seek_descriptor->offset, SEEK_END); 00305 errsv = errno; 00306 ReleaseTokenFSCall(); 00307 00308 default: 00309 rc = -1; 00310 errsv = EINVAL; 00311 00312 break; 00313 } 00314 00315 if(rc) 00316 { 00317 LogEvent(COMPONENT_FSAL, 00318 "Error in posix fseek operation (whence=%s, offset=%"PRId64")", 00319 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00320 (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : 00321 (p_seek_descriptor->whence == 00322 FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), 00323 p_seek_descriptor->offset); 00324 00325 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_read); 00326 } 00327 00328 } 00329 00330 /* read operation */ 00331 00332 TakeTokenFSCall(); 00333 00334 if(pcall) 00335 nb_read = pread(((xfsfsal_file_t *)p_file_descriptor)->fd, buffer, 00336 i_size, p_seek_descriptor->offset); 00337 else 00338 nb_read = read(((xfsfsal_file_t *)p_file_descriptor)->fd, buffer, i_size); 00339 errsv = errno; 00340 ReleaseTokenFSCall(); 00341 00344 if(nb_read == -1) 00345 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_read); 00346 else if(nb_read == 0) 00347 *p_end_of_file = 1; 00348 00349 *p_read_amount = nb_read; 00350 00351 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); 00352 00353 } 00354 00378 fsal_status_t XFSFSAL_write(fsal_file_t * p_file_descriptor, /* IN */ 00379 fsal_op_context_t * p_context, /* IN */ 00380 fsal_seek_t * p_seek_descriptor, /* IN */ 00381 fsal_size_t buffer_size, /* IN */ 00382 caddr_t buffer, /* IN */ 00383 fsal_size_t * p_write_amount /* OUT */ 00384 ) 00385 { 00386 00387 ssize_t nb_written; 00388 size_t i_size; 00389 int rc, errsv; 00390 int pcall = FALSE; 00391 00392 /* sanity checks. */ 00393 if(!p_file_descriptor || !buffer || !p_write_amount) 00394 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); 00395 00396 if(((xfsfsal_file_t *)p_file_descriptor)->ro) 00397 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_write); 00398 00400 i_size = (size_t) buffer_size; 00401 00402 *p_write_amount = 0; 00403 00404 /* positioning */ 00405 00406 if(p_seek_descriptor) 00407 { 00408 00409 switch (p_seek_descriptor->whence) 00410 { 00411 case FSAL_SEEK_CUR: 00412 /* set position plus offset */ 00413 pcall = FALSE; 00414 00415 TakeTokenFSCall(); 00416 rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, p_seek_descriptor->offset, SEEK_CUR); 00417 errsv = errno; 00418 ReleaseTokenFSCall(); 00419 break; 00420 00421 case FSAL_SEEK_SET: 00422 /* set absolute position to offset */ 00423 pcall = TRUE; 00424 rc = 0; 00425 errsv = 0; 00426 break; 00427 00428 case FSAL_SEEK_END: 00429 /* set end of file plus offset */ 00430 pcall = FALSE; 00431 00432 TakeTokenFSCall(); 00433 rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, p_seek_descriptor->offset, SEEK_END); 00434 errsv = errno; 00435 ReleaseTokenFSCall(); 00436 00437 break; 00438 default: 00439 rc = -1; 00440 errsv = EINVAL; 00441 break; 00442 } 00443 00444 if(rc) 00445 { 00446 LogEvent(COMPONENT_FSAL, 00447 "Error in posix fseek operation (whence=%s, offset=%"PRId64")", 00448 (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : 00449 (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : 00450 (p_seek_descriptor->whence == 00451 FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), 00452 p_seek_descriptor->offset); 00453 00454 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); 00455 00456 } 00457 00458 LogFullDebug(COMPONENT_FSAL, 00459 "Write operation (whence=%s, offset=%"PRId64", size=%zu)", 00460 (p_seek_descriptor->whence == 00461 FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == 00462 FSAL_SEEK_SET ? "SEEK_SET" 00463 : (p_seek_descriptor->whence == 00464 FSAL_SEEK_END ? "SEEK_END" : 00465 "ERROR"))), 00466 p_seek_descriptor->offset, buffer_size); 00467 00468 } 00469 00470 /* write operation */ 00471 00472 TakeTokenFSCall(); 00473 00474 if(pcall) 00475 nb_written = pwrite(((xfsfsal_file_t *)p_file_descriptor)->fd, 00476 buffer, i_size, p_seek_descriptor->offset); 00477 else 00478 nb_written = write(((xfsfsal_file_t *)p_file_descriptor)->fd, buffer, i_size); 00479 errsv = errno; 00480 00481 ReleaseTokenFSCall(); 00482 00484 if(nb_written <= 0) 00485 { 00486 LogDebug(COMPONENT_FSAL, 00487 "Write operation of size %zu at offset %"PRId64" failed. fd=%d, errno=%d.", 00488 i_size, p_seek_descriptor->offset, 00489 ((xfsfsal_file_t *)p_file_descriptor)->fd, errsv); 00490 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); 00491 } 00492 00493 /* set output vars */ 00494 00495 *p_write_amount = (fsal_size_t) nb_written; 00496 00497 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); 00498 00499 } 00500 00513 fsal_status_t XFSFSAL_close(fsal_file_t * p_file_descriptor /* IN */ 00514 ) 00515 { 00516 00517 int rc, errsv; 00518 00519 /* sanity checks. */ 00520 if(!p_file_descriptor) 00521 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close); 00522 00523 if(((xfsfsal_file_t *)p_file_descriptor)->fd == 0 ) 00524 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00525 00526 /* call to close */ 00527 00528 TakeTokenFSCall(); 00529 00530 rc = close(((xfsfsal_file_t *)p_file_descriptor)->fd); 00531 errsv = errno; 00532 00533 ReleaseTokenFSCall(); 00534 00535 if(rc) 00536 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_close); 00537 00538 ((xfsfsal_file_t *)p_file_descriptor)->fd = 0 ; 00539 00540 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00541 00542 } 00543 00544 unsigned int XFSFSAL_GetFileno(fsal_file_t * pfile) 00545 { 00546 return ((xfsfsal_file_t *) pfile)->fd; 00547 } 00548 00566 fsal_status_t XFSFSAL_commit( fsal_file_t * p_file_descriptor, 00567 fsal_off_t offset, 00568 fsal_size_t length ) 00569 { 00570 int rc, errsv; 00571 00572 /* sanity checks. */ 00573 if(!p_file_descriptor) 00574 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_commit); 00575 00576 if(((xfsfsal_file_t *)p_file_descriptor)->fd == 0 ) 00577 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); /* Nothing to sync, the file is not opened */ 00578 00579 /* Flush data. */ 00580 TakeTokenFSCall(); 00581 rc = fsync(((xfsfsal_file_t *)p_file_descriptor)->fd); 00582 errsv = errno; 00583 ReleaseTokenFSCall(); 00584 00585 if(rc) 00586 { 00587 LogEvent(COMPONENT_FSAL, "Error in fsync operation"); 00588 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_commit); 00589 } 00590 00591 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); 00592 } 00593