nfs-ganesha 1.4

fsal_fileop.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010 The Linx Box Corporation
00003  * Contributor : Adam C. Emerson
00004  *
00005  * Some Portions Copyright CEA/DAM/DIF  (2008)
00006  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00007  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00008  *
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 3 of the License, or (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023  *
00024  * ---------------------------------------
00025  */
00026 
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035 
00036 #include "fsal.h"
00037 #include "fsal_internal.h"
00038 #include "fsal_convert.h"
00039 #include <stdio.h>
00040 
00077 fsal_status_t CEPHFSAL_open(fsal_handle_t * exthandle,
00078                             fsal_op_context_t * extcontext,
00079                             fsal_openflags_t openflags,
00080                             fsal_file_t * extdescriptor,
00081                             fsal_attrib_list_t * file_attributes)
00082 {
00083   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00084   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00085   cephfsal_file_t* descriptor = (cephfsal_file_t *) extdescriptor;
00086   struct ceph_mount_info *cmount = context->export_context->cmount;
00087   int rc = 0;
00088   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00089   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00090   int posix_flags = 0;
00091   Fh *desc = NULL;
00092 
00093   /* sanity checks.
00094    * note : file_attributes is optional.
00095    */
00096   if(!handle || !context || !descriptor)
00097     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open);
00098 
00099   rc = fsal2posix_openflags(openflags, &posix_flags);
00100 
00101   /* flags conflicts. */
00102   if(rc)
00103     Return(rc, 0, INDEX_FSAL_open);
00104 
00105   TakeTokenFSCall();
00106 
00107   rc = ceph_ll_open(cmount, VINODE(handle), posix_flags, &desc, uid, gid);
00108 
00109   descriptor->fh = desc;
00110   descriptor->vi = VINODE(handle);
00111   descriptor->ctx = *context;
00112 
00113   ReleaseTokenFSCall();
00114 
00115   if (rc < 0)
00116     Return(posix2fsal_error(rc), 0, INDEX_FSAL_open);
00117 
00118   if(file_attributes)
00119     {
00120       fsal_status_t status
00121         = CEPHFSAL_getattrs(exthandle, extcontext, file_attributes);
00122 
00123       if(FSAL_IS_ERROR(status))
00124         {
00125           FSAL_CLEAR_MASK(file_attributes->asked_attributes);
00126           FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00127         }
00128     }
00129 
00130   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open);
00131 }
00132 
00172 fsal_status_t CEPHFSAL_open_by_name(fsal_handle_t * exthandle,
00173                                     fsal_name_t * filename,
00174                                     fsal_op_context_t * extcontext,
00175                                     fsal_openflags_t openflags,
00176                                     fsal_file_t * extdescriptor,
00177                                     fsal_attrib_list_t * file_attributes)
00178 {
00179   fsal_status_t fsal_status;
00180   fsal_handle_t found;
00181 
00182   if(!exthandle || !filename || !extcontext || !extdescriptor)
00183     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name);
00184 
00185   fsal_status =
00186     CEPHFSAL_lookup(exthandle, filename, extcontext, &found, file_attributes);
00187 
00188   if(FSAL_IS_ERROR(fsal_status))
00189     return fsal_status;
00190 
00191   return CEPHFSAL_open(&found, extcontext, openflags, extdescriptor,
00192                        file_attributes);
00193 }
00194 
00223 fsal_status_t CEPHFSAL_read(fsal_file_t * extdescriptor,
00224                             fsal_seek_t * seek_descriptor,
00225                             fsal_size_t buffer_size,
00226                             caddr_t buffer,
00227                             fsal_size_t * read_amount,
00228                             fsal_boolean_t * end_of_file)
00229 {
00230   cephfsal_file_t* descriptor = (cephfsal_file_t*) extdescriptor;
00231   struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount;
00232 
00233   int nb_read = 0;
00234   fsal_off_t offset;
00235 
00236   /* sanity checks. */
00237 
00238   if(!descriptor || !buffer || !read_amount || !end_of_file)
00239     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read);
00240 
00241   if (seek_descriptor)
00242     {
00243       if (seek_descriptor->whence != FSAL_SEEK_SET)
00244         {
00245           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_write);
00246         }
00247       else
00248         {
00249           offset = seek_descriptor->offset;
00250         }
00251     }
00252   else
00253     {
00254       offset = 0;
00255     }
00256 
00257   TakeTokenFSCall();
00258 
00259   nb_read = ceph_ll_read(cmount, FH(descriptor), offset, buffer_size, buffer);
00260 
00261   ReleaseTokenFSCall();
00262 
00263   if (nb_read < 0)
00264     Return(posix2fsal_error(nb_read), 0, INDEX_FSAL_read);
00265 
00266   if (nb_read < buffer_size)
00267     *end_of_file = TRUE;
00268   else
00269     *end_of_file = FALSE;
00270 
00271   *read_amount = nb_read;
00272 
00273   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read);
00274 }
00275 
00303 fsal_status_t CEPHFSAL_write(fsal_file_t * extdescriptor,
00304                              fsal_op_context_t * p_context,
00305                              fsal_seek_t * seek_descriptor,
00306                              fsal_size_t buffer_size,
00307                              caddr_t buffer,
00308                              fsal_size_t * write_amount)
00309 {
00310   cephfsal_file_t* descriptor = (cephfsal_file_t*) extdescriptor;
00311   struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount;
00312   int nb_written=0;
00313   fsal_off_t offset;
00314 
00315   /* sanity checks. */
00316   if(!descriptor || !buffer || !write_amount)
00317     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write);
00318 
00319   if (seek_descriptor)
00320     {
00321       if (seek_descriptor->whence != FSAL_SEEK_SET)
00322         {
00323           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_write);
00324         }
00325       else
00326         {
00327           offset = seek_descriptor->offset;
00328         }
00329     }
00330   else
00331     {
00332       offset = 0;
00333     }
00334 
00335   TakeTokenFSCall();
00336 
00337   nb_written = ceph_ll_write(cmount, FH(descriptor), offset, buffer_size,
00338                              buffer);
00339 
00340   ReleaseTokenFSCall();
00341 
00342   if (nb_written < 0)
00343     Return(posix2fsal_error(nb_written), 0, INDEX_FSAL_write);
00344 
00345   *write_amount = nb_written;
00346 
00347   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write);
00348 
00349 }
00350 
00365 fsal_status_t CEPHFSAL_close(fsal_file_t * extdescriptor)
00366 {
00367   cephfsal_file_t* descriptor = (cephfsal_file_t*) extdescriptor;
00368   struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount;
00369   int rc = 0;
00370 
00371   /* sanity checks. */
00372   if(!descriptor)
00373     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);
00374 
00375   /* This is because of a bug in the cache layer which must be fixed
00376      later.  Right now, we work around it. */
00377 
00378   if(!FH(descriptor))
00379     Return(ERR_FSAL_NOT_OPENED, 0, INDEX_FSAL_close);
00380 
00381   TakeTokenFSCall();
00382 
00383   rc = ceph_ll_close(cmount, FH(descriptor));
00384 
00385   ReleaseTokenFSCall();
00386 
00387   FH(descriptor) = NULL;
00388 
00389   if (rc != 0)
00390     Return(posix2fsal_error(rc), 0, INDEX_FSAL_read);
00391 
00392   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);
00393 
00394 }
00395 
00396 unsigned int CEPHFSAL_GetFileno(fsal_file_t * pfile)
00397 {
00398   unsigned int mask=0xFFFFFFFF;
00399   return (mask & ((uintptr_t) FH((cephfsal_file_t*) pfile)));
00400 }
00401 
00419 fsal_status_t CEPHFSAL_commit( fsal_file_t * extdescriptor, 
00420                              fsal_off_t    offset, 
00421                              fsal_size_t   length )
00422 {
00423   cephfsal_file_t* descriptor = (cephfsal_file_t*) extdescriptor;
00424   struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount;
00425   int rc = 0;
00426 
00427   /* sanity checks. */
00428   if(!extdescriptor)
00429     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_commit);
00430 
00431   TakeTokenFSCall();
00432   if ((rc = ceph_ll_fsync(cmount, FH(descriptor), 0)) < 0)
00433     {
00434       Return(posix2fsal_error(rc), 0, INDEX_FSAL_commit);
00435     }
00436   ReleaseTokenFSCall();
00437 
00438   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit);
00439 }