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_common.h" 00019 #include "fsal_internal.h" 00020 #include "fsal_convert.h" 00021 00058 fsal_status_t ZFSFSAL_open(fsal_handle_t * file_hdl, /* IN */ 00059 fsal_op_context_t * p_context, /* IN */ 00060 fsal_openflags_t openflags, /* IN */ 00061 fsal_file_t * file_desc, /* OUT */ 00062 fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ 00063 ) 00064 { 00065 int rc; 00066 creden_t cred; 00067 zfsfsal_handle_t * filehandle = (zfsfsal_handle_t *)file_hdl; 00068 zfsfsal_file_t * file_descriptor = ( zfsfsal_file_t *)file_desc; 00069 00070 /* sanity checks. 00071 * note : file_attributes is optional. 00072 */ 00073 if(!filehandle || !p_context || !file_descriptor) 00074 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); 00075 00076 /* Check if this is a file */ 00077 if(filehandle->data.type != FSAL_TYPE_FILE) 00078 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open); 00079 00080 /* Get the right VFS */ 00081 ZFSFSAL_VFS_RDLock(); 00082 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(filehandle); 00083 if(!p_vfs) 00084 { 00085 ZFSFSAL_VFS_Unlock(); 00086 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_open); 00087 } 00088 00089 /* >> convert fsal open flags to your FS open flags 00090 * Take care of conflicting flags << */ 00091 int posix_flags; 00092 rc = fsal2posix_openflags(openflags, &posix_flags); 00093 if(rc) 00094 Return(rc, 0, INDEX_FSAL_open); 00095 cred.uid = p_context->credential.user; 00096 cred.gid = p_context->credential.group; 00097 00098 TakeTokenFSCall(); 00099 00100 /* >> call your FS open function << */ 00101 libzfswrap_vnode_t *p_vnode; 00102 rc = libzfswrap_open(p_vfs, &cred, 00103 filehandle->data.zfs_handle, posix_flags, &p_vnode); 00104 00105 ReleaseTokenFSCall(); 00106 ZFSFSAL_VFS_Unlock(); 00107 00108 /* >> interpret returned status << */ 00109 if(rc) 00110 Return(posix2fsal_error(rc), 0, INDEX_FSAL_open); 00111 00112 /* >> fill output struct << */ 00113 file_descriptor->flags = posix_flags; 00114 file_descriptor->current_offset = 0; 00115 file_descriptor->p_vnode = p_vnode; 00116 file_descriptor->handle = *filehandle; 00117 file_descriptor->cred = cred; 00118 file_descriptor->is_closed = 0; 00119 00120 if(file_attributes) 00121 { 00122 fsal_status_t status = ZFSFSAL_getattrs(file_hdl, p_context, file_attributes); 00123 /* On error, we set a flag in the returned attributes */ 00124 if(FSAL_IS_ERROR(status)) 00125 { 00126 FSAL_CLEAR_MASK(file_attributes->asked_attributes); 00127 FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00128 } 00129 } 00130 00131 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open); 00132 } 00133 00173 fsal_status_t ZFSFSAL_open_by_name(fsal_handle_t * dirhandle, /* IN */ 00174 fsal_name_t * filename, /* IN */ 00175 fsal_op_context_t * p_context, /* IN */ 00176 fsal_openflags_t openflags, /* IN */ 00177 fsal_file_t * file_descriptor, /* OUT */ 00178 fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ ) 00179 { 00180 fsal_status_t fsal_status; 00181 fsal_handle_t filehandle; 00182 00183 if(!dirhandle || !filename || !p_context || !file_descriptor) 00184 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); 00185 00186 fsal_status = ZFSFSAL_lookup(dirhandle, filename, p_context, &filehandle, file_attributes); 00187 if(FSAL_IS_ERROR(fsal_status)) 00188 return fsal_status; 00189 00190 return ZFSFSAL_open(&filehandle, p_context, openflags, file_descriptor, file_attributes); 00191 } 00192 00221 fsal_status_t ZFSFSAL_read(fsal_file_t * file_desc, /* IN */ 00222 fsal_seek_t * seek_descriptor, /* [IN] */ 00223 fsal_size_t buffer_size, /* IN */ 00224 caddr_t buffer, /* OUT */ 00225 fsal_size_t * read_amount, /* OUT */ 00226 fsal_boolean_t * end_of_file /* OUT */ 00227 ) 00228 { 00229 off_t offset = 0; 00230 int rc; 00231 int behind = 0; 00232 zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc; 00233 00234 /* sanity checks. */ 00235 00236 if(!file_descriptor || !buffer || !read_amount || !end_of_file) 00237 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); 00238 00239 TakeTokenFSCall(); 00240 00241 if(seek_descriptor) 00242 { 00243 switch(seek_descriptor->whence) 00244 { 00245 case FSAL_SEEK_CUR: 00246 offset = file_descriptor->current_offset + seek_descriptor->offset; 00247 break; 00248 case FSAL_SEEK_SET: 00249 offset = seek_descriptor->offset; 00250 break; 00251 case FSAL_SEEK_END: 00252 behind = 1; 00253 offset = seek_descriptor->offset; 00254 break; 00255 } 00256 } 00257 00258 /* Test that the vfs still exist */ 00259 ZFSFSAL_VFS_RDLock(); 00260 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle); 00261 if(!p_vfs) 00262 { 00263 ZFSFSAL_VFS_Unlock(); 00264 ReleaseTokenFSCall(); 00265 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_read); 00266 } 00267 00268 rc = libzfswrap_read(p_vfs, &file_descriptor->cred, file_descriptor->p_vnode, buffer, buffer_size, behind, offset); 00269 ZFSFSAL_VFS_Unlock(); 00270 00271 ReleaseTokenFSCall(); 00272 00273 /* >> interpreted returned status << */ 00274 if(!rc) 00275 *end_of_file = 1; 00276 00277 /* >> dont forget setting output vars : read_amount, end_of_file << */ 00278 *read_amount = buffer_size; 00279 00280 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); 00281 00282 } 00283 00311 fsal_status_t ZFSFSAL_write(fsal_file_t * file_desc, /* IN */ 00312 fsal_op_context_t * p_context, /* IN */ 00313 fsal_seek_t * seek_descriptor, /* IN */ 00314 fsal_size_t buffer_size, /* IN */ 00315 caddr_t buffer, /* IN */ 00316 fsal_size_t * write_amount /* OUT */ 00317 ) 00318 { 00319 int rc, behind = 0; 00320 off_t offset; 00321 zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc; 00322 00323 /* sanity checks. */ 00324 if(!file_descriptor || !buffer || !write_amount) 00325 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); 00326 00327 /* Hook to prevent writing into a snapshot */ 00328 if(file_descriptor->handle.data.i_snap != 0) 00329 { 00330 LogDebug(COMPONENT_FSAL, "Trying to write to a file inside a snapshot"); 00331 Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_write); 00332 } 00333 00334 TakeTokenFSCall(); 00335 00336 if(seek_descriptor) 00337 { 00338 switch(seek_descriptor->whence) 00339 { 00340 case FSAL_SEEK_CUR: 00341 offset = file_descriptor->current_offset + seek_descriptor->offset; 00342 break; 00343 case FSAL_SEEK_SET: 00344 offset = seek_descriptor->offset; 00345 break; 00346 case FSAL_SEEK_END: 00347 behind = 1; 00348 offset = seek_descriptor->offset; 00349 break; 00350 } 00351 } 00352 /* Test that the vfs still exist */ 00353 ZFSFSAL_VFS_RDLock(); 00354 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle); 00355 if(!p_vfs) 00356 { 00357 ZFSFSAL_VFS_Unlock(); 00358 ReleaseTokenFSCall(); 00359 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_write); 00360 } 00361 00362 00363 rc = libzfswrap_write(p_vfs, &file_descriptor->cred, file_descriptor->p_vnode, buffer, buffer_size, behind, offset); 00364 ZFSFSAL_VFS_Unlock(); 00365 00366 ReleaseTokenFSCall(); 00367 00368 /* >> interpreted returned status << */ 00369 if(rc) 00370 Return(posix2fsal_error(rc), 0, INDEX_FSAL_write); 00371 00372 /* >> dont forget setting output vars : write_amount << */ 00373 *write_amount = buffer_size; 00374 00375 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); 00376 00377 } 00378 00393 fsal_status_t ZFSFSAL_close(fsal_file_t * file_desc /* IN */ 00394 ) 00395 { 00396 int rc = 0; 00397 zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc; 00398 00399 /* sanity checks. */ 00400 if(!file_descriptor) 00401 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close); 00402 00403 TakeTokenFSCall(); 00404 00405 if(!file_descriptor->is_closed) 00406 { 00407 /* Test that the vfs still exist */ 00408 ZFSFSAL_VFS_RDLock(); 00409 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle); 00410 if(!p_vfs) 00411 { 00412 ZFSFSAL_VFS_Unlock(); 00413 ReleaseTokenFSCall(); 00414 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_close); 00415 } 00416 00417 rc = libzfswrap_close(p_vfs, &file_descriptor->cred, file_descriptor->p_vnode, 00418 file_descriptor->flags); 00419 ZFSFSAL_VFS_Unlock(); 00420 file_descriptor->is_closed = 1; 00421 } 00422 00423 ReleaseTokenFSCall(); 00424 00425 if(rc) 00426 Return(posix2fsal_error(rc), rc, INDEX_FSAL_close); 00427 00428 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close); 00429 00430 } 00431 00432 unsigned int ZFSFSAL_GetFileno(fsal_file_t * pfile) 00433 { 00434 return ((zfsfsal_file_t *) pfile)->handle.data.zfs_handle.inode; 00435 } 00436 00454 fsal_status_t ZFSFSAL_commit(fsal_file_t * p_file_descriptor, 00455 fsal_off_t offset, 00456 fsal_size_t length ) 00457 { 00458 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); 00459 }