nfs-ganesha 1.4

fsal_fileop.c

Go to the documentation of this file.
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 }