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 #ifdef _SOLARIS
00018 #include "solaris_port.h"
00019 #endif                          /* _SOLARIS */
00020 
00021 #include <string.h>
00022 #ifdef _USE_GSSRPC
00023 #include <gssrpc/rpc.h>
00024 #include <gssrpc/xdr.h>
00025 #else
00026 #include <rpc/rpc.h>
00027 #include <rpc/xdr.h>
00028 #endif
00029 #include "nfs4.h"
00030 
00031 #include "fsal_internal.h"
00032 #include "fsal_convert.h"
00033 #include "fsal_common.h"
00034 
00035 #include "nfs_proto_functions.h"
00036 #include "fsal_nfsv4_macros.h"
00037 #include "abstract_mem.h"
00038 
00039 #ifdef _APPLE
00040 #define strnlen( s, l ) strlen( s )
00041 #endif
00042 
00081 fsal_status_t PROXYFSAL_open_by_name(fsal_handle_t * dirhandle,    /* IN */
00082                                      fsal_name_t * filename,    /* IN */
00083                                      fsal_op_context_t *context,        /* IN */
00084                                      fsal_openflags_t openflags,        /* IN */
00085                                      fsal_file_t * file_desc,        /* OUT */
00086                                      fsal_attrib_list_t * file_attributes       /* [ IN/OUT ] */
00087     )
00088 {
00089   int rc;
00090   COMPOUND4args argnfs4;
00091   COMPOUND4res resnfs4;
00092   nfs_fh4 nfs4fh;
00093   bitmap4 bitmap;
00094   uint32_t bitmap_res[2];
00095   uint32_t bitmap_open[2];
00096   uint32_t bitmap_getattr_res[2];
00097   uint32_t share_access;
00098   component4 name;
00099   char nameval[MAXNAMLEN];
00100   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00101   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00102 
00103 #define FSAL_OPEN_NB_OP_ALLOC 4
00104 #define FSAL_OPEN_VAL_BUFFER  1024
00105 
00106   fsal_proxy_internal_fattr_t fattr_internal;
00107   fsal_attrib_list_t attributes;
00108   nfs_argop4 argoparray[FSAL_OPEN_NB_OP_ALLOC];
00109   nfs_resop4 resoparray[FSAL_OPEN_NB_OP_ALLOC];
00110   char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
00111   fsal_status_t fsal_status;
00112   struct timeval timeout = TIMEOUTRPC;
00113   char owner_val[FSAL_PROXY_OWNER_LEN];
00114   unsigned int owner_len = 0;
00115 
00116   /* sanity checks.
00117    * note : file_attributes is optional.
00118    */
00119   if(!dirhandle || !filename || !p_context || !file_descriptor)
00120     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name);
00121 
00122   PRINT_HANDLE("FSAL_open", dirhandle);
00123 
00124   if(((proxyfsal_handle_t *)dirhandle)->data.object_type_reminder != FSAL_TYPE_DIR)
00125     {
00126       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_name);
00127     }
00128 
00129   /* Create the owner */
00130   snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu",
00131            getpid(), p_context, (unsigned long long int)p_context->file_counter);
00132   owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN);
00133   p_context->file_counter += 1;
00134 
00135   /* Setup results structures */
00136   argnfs4.argarray.argarray_val = argoparray;
00137   resnfs4.resarray.resarray_val = resoparray;
00138   argnfs4.minorversion = 0;
00139   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */
00140   argnfs4.tag.utf8string_val = NULL;
00141   argnfs4.tag.utf8string_len = 0;
00142   argnfs4.argarray.argarray_len = 0;
00143 
00144   fsal_internal_proxy_setup_fattr(&fattr_internal);
00145 
00146   memset(&name, 0, sizeof(component4));
00147   name.utf8string_val = nameval;
00148   name.utf8string_len = sizeof(nameval);
00149   if(fsal_internal_proxy_fsal_name_2_utf8(filename, &name) == FALSE)
00150     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name);
00151 
00152 
00153   /* Get NFSv4 File handle */
00154   if(fsal_internal_proxy_extract_fh(&nfs4fh, dirhandle) == FALSE)
00155     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name);
00156 
00157   bitmap.bitmap4_val = bitmap_open;
00158   bitmap.bitmap4_len = 2;
00159 
00160   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00161 
00162   share_access = 0;
00163   if((openflags & FSAL_O_RDWR) == FSAL_O_RDWR)
00164     share_access |= OPEN4_SHARE_ACCESS_BOTH;
00165 
00166   if((openflags & FSAL_O_RDONLY) == FSAL_O_RDONLY)
00167     share_access |= OPEN4_SHARE_ACCESS_READ;
00168 
00169   if(((openflags & FSAL_O_WRONLY) == FSAL_O_WRONLY) ||
00170      ((openflags & FSAL_O_APPEND) == FSAL_O_APPEND))
00171     share_access |= OPEN4_SHARE_ACCESS_WRITE;
00172 
00173   /* >> you can check if this is a file if the information
00174    * is stored into the handle << */
00175 #define FSAL_OPEN_IDX_OP_PUTFH         0
00176 #define FSAL_OPEN_IDX_OP_OPEN_NOCREATE 1
00177 #define FSAL_OPEN_IDX_OP_GETFH         2
00178 #define FSAL_OPEN_IDX_OP_GETATTR       3
00179   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00180   COMPOUNDV4_ARG_ADD_OP_OPEN_NOCREATE(argnfs4, file_descriptor->stateid.seqid,
00181                                       p_context->clientid, share_access, name, owner_val,
00182                                       owner_len);
00183   COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
00184   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00185 
00186   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
00187       OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res;
00188   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
00189       OPEN4res_u.resok4.attrset.bitmap4_len = 2;
00190 
00191   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00192       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
00193   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00194       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00195 
00196   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00197       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00198       (char *)&fattr_internal;
00199   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00200       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00201       sizeof(fattr_internal);
00202 
00203   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u.
00204       resok4.object.nfs_fh4_val = (char *)padfilehandle;
00205   resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u.
00206       resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
00207 
00208   TakeTokenFSCall();
00209 
00210   /* Call the NFSv4 function */
00211   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00212   if(rc != RPC_SUCCESS)
00213     {
00214       ReleaseTokenFSCall();
00215       Return(ERR_FSAL_IO, rc, INDEX_FSAL_open_by_name);
00216     }
00217 
00218   ReleaseTokenFSCall();
00219 
00220   /* >> convert error code, and return on error << */
00221   if(resnfs4.status != NFS4_OK)
00222     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open_by_name);
00223 
00224   /* Use NFSv4 service function to build the FSAL_attr */
00225   if(nfs4_Fattr_To_FSAL_attr(&attributes,
00226                              &resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETATTR].
00227                              nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
00228                              obj_attributes) != NFS4_OK)
00229     {
00230       FSAL_CLEAR_MASK(file_attributes->asked_attributes);
00231       FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00232 
00233       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_name);
00234     }
00235 
00236   if(file_attributes)
00237     {
00238       memcpy(file_attributes, &attributes, sizeof(attributes));
00239     }
00240 
00241   /* >> fill output struct << */
00242   /* Build the handle */
00243   if(fsal_internal_proxy_create_fh
00244      (&resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00245       GETFH4res_u.resok4.object, FSAL_TYPE_FILE, attributes.fileid,
00246       (fsal_handle_t *) &file_descriptor->fhandle) == FALSE)
00247     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name);
00248 
00249   file_descriptor->openflags = openflags;
00250   file_descriptor->current_offset = 0;
00251   file_descriptor->pcontext = p_context;
00252 
00253   /* Keep the returned stateid for later use */
00254   file_descriptor->stateid.seqid =
00255       resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
00256       OPEN4res_u.resok4.stateid.seqid;
00257   memcpy((char *)file_descriptor->stateid.other,
00258          resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.
00259          opopen.OPEN4res_u.resok4.stateid.other, 12);
00260 
00261   /* See if a OPEN_CONFIRM is required */
00262   if(resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
00263      OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM)
00264     {
00265       fsal_status = FSAL_proxy_open_confirm(file_descriptor);
00266       if(FSAL_IS_ERROR(fsal_status))
00267         Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_open_by_name);
00268     }
00269 
00270   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open_by_name);
00271 }                               /* FSAL_open_by_name */
00272 
00309 fsal_status_t PROXYFSAL_open(fsal_handle_t * filehandle,  /* IN */
00310                              fsal_op_context_t *context,       /* IN */
00311                              fsal_openflags_t openflags,       /* IN */
00312                              fsal_file_t * file_desc,       /* OUT */
00313                              fsal_attrib_list_t * file_attributes      /* [ IN/OUT ] */
00314     )
00315 {
00316   int rc;
00317   COMPOUND4args argnfs4;
00318   COMPOUND4res resnfs4;
00319   nfs_fh4 nfs4fh;
00320   bitmap4 bitmap;
00321   uint32_t bitmap_open[2];
00322   uint32_t bitmap_getattr_res[2];
00323   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00324   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00325 
00326 #define FSAL_OPEN_STATELESS_NB_OP_ALLOC 2
00327 #define FSAL_OPEN_STATELESS_VAL_BUFFER  1024
00328 
00329   fsal_proxy_internal_fattr_t fattr_internal;
00330   fsal_attrib_list_t attributes;
00331   nfs_argop4 argoparray[FSAL_OPEN_STATELESS_NB_OP_ALLOC];
00332   nfs_resop4 resoparray[FSAL_OPEN_STATELESS_NB_OP_ALLOC];
00333   struct timeval timeout = TIMEOUTRPC;
00334 
00335   /* sanity checks.
00336    * note : file_attributes is optional.
00337    */
00338   if(!filehandle || !p_context || !file_descriptor)
00339     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open);
00340 
00341   PRINT_HANDLE("FSAL_open_stateless", filehandle);
00342 
00343   if(((proxyfsal_handle_t *)filehandle)->data.object_type_reminder != FSAL_TYPE_FILE)
00344     {
00345       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open);
00346     }
00347 
00348   /* Setup results structures */
00349   argnfs4.argarray.argarray_val = argoparray;
00350   resnfs4.resarray.resarray_val = resoparray;
00351   argnfs4.minorversion = 0;
00352   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */
00353   argnfs4.tag.utf8string_val = NULL;
00354   argnfs4.tag.utf8string_len = 0;
00355   argnfs4.argarray.argarray_len = 0;
00356 
00357   fsal_internal_proxy_setup_fattr(&fattr_internal);
00358 
00359   /* Get NFSv4 File handle */
00360   if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE)
00361     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open);
00362 
00363   bitmap.bitmap4_val = bitmap_open;
00364   bitmap.bitmap4_len = 2;
00365   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00366 
00367 #define FSAL_OPEN_STATELESS_IDX_OP_PUTFH         0
00368 #define FSAL_OPEN_STATELESS_IDX_OP_GETATTR       1
00369   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00370   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00371 
00372   resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
00373       opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val =
00374       bitmap_getattr_res;
00375   resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
00376       opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00377 
00378   resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
00379       opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00380       (char *)&fattr_internal;
00381   resnfs4.resarray.resarray_val[FSAL_OPEN_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
00382       opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00383       sizeof(fattr_internal);
00384 
00385   TakeTokenFSCall();
00386 
00387   /* Call the NFSv4 function */
00388   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00389   if(rc != RPC_SUCCESS)
00390     {
00391       ReleaseTokenFSCall();
00392       Return(ERR_FSAL_IO, rc, INDEX_FSAL_open);
00393     }
00394 
00395   ReleaseTokenFSCall();
00396 
00397   /* >> convert error code, and return on error << */
00398   if(resnfs4.status != NFS4_OK)
00399     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open);
00400 
00401   /* Use NFSv4 service function to build the FSAL_attr */
00402   if(file_attributes)
00403     {
00404       if(nfs4_Fattr_To_FSAL_attr(&attributes,
00405                                  &resnfs4.resarray.resarray_val
00406                                  [FSAL_OPEN_STATELESS_IDX_OP_GETATTR].
00407                                  nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
00408                                  obj_attributes) != NFS4_OK)
00409         {
00410           FSAL_CLEAR_MASK(file_attributes->asked_attributes);
00411           FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00412 
00413           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open);
00414         }
00415 
00416       memcpy(file_attributes, &attributes, sizeof(attributes));
00417     }
00418 
00419   /* >> fill output struct << */
00420   memcpy((char *)&file_descriptor->fhandle, filehandle, sizeof(proxyfsal_handle_t));
00421   file_descriptor->openflags = openflags;
00422   file_descriptor->current_offset = 0;
00423   file_descriptor->pcontext = p_context;
00424 
00425   /* Keep the returned stateid for later use */
00426   file_descriptor->stateid.seqid = 0;
00427   memset((char *)file_descriptor->stateid.other, 0, 12);
00428 
00429   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open);
00430 }                               /* FSAL_open */
00431 
00460 fsal_status_t PROXYFSAL_read(fsal_file_t * file_desc,        /* IN */
00461                              fsal_seek_t * seek_descriptor,     /* IN */
00462                              fsal_size_t buffer_size,   /* IN */
00463                              caddr_t buffer,    /* OUT */
00464                              fsal_size_t * read_amount, /* OUT */
00465                              fsal_boolean_t * end_of_file       /* OUT */
00466     )
00467 {
00468   int rc;
00469   COMPOUND4args argnfs4;
00470   COMPOUND4res resnfs4;
00471   nfs_fh4 nfs4fh;
00472   fsal_off_t offset;
00473   struct timeval timeout = TIMEOUTRPC;
00474   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00475 
00476 #define FSAL_READ_NB_OP_ALLOC 2
00477 
00478   nfs_argop4 argoparray[FSAL_READ_NB_OP_ALLOC];
00479   nfs_resop4 resoparray[FSAL_READ_NB_OP_ALLOC];
00480 
00481   /* sanity checks. */
00482 
00483   if(!file_descriptor || !buffer || !read_amount || !end_of_file)
00484     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read);
00485 
00486   if(seek_descriptor == NULL)
00487     offset = file_descriptor->current_offset;
00488   else
00489     {
00490       switch (seek_descriptor->whence)
00491         {
00492         case FSAL_SEEK_SET:
00493           offset = seek_descriptor->offset;
00494           break;
00495 
00496         case FSAL_SEEK_CUR:
00497           offset = seek_descriptor->offset + file_descriptor->current_offset;
00498           break;
00499 
00500         default:
00501         case FSAL_SEEK_END:
00502           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_read);
00503           break;
00504         }
00505     }
00506 
00507   /* Setup results structures */
00508   argnfs4.argarray.argarray_val = argoparray;
00509   resnfs4.resarray.resarray_val = resoparray;
00510   argnfs4.minorversion = 0;
00511   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Read" ; */
00512   argnfs4.tag.utf8string_val = NULL;
00513   argnfs4.tag.utf8string_len = 0;
00514   argnfs4.argarray.argarray_len = 0;
00515 
00516   /* Get NFSv4 File handle */
00517   if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &(file_descriptor->fhandle)) == FALSE)
00518     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read);
00519 
00520 #define FSAL_READ_IDX_OP_PUTFH   0
00521 #define FSAL_READ_IDX_OP_READ    1
00522 
00523   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00524   COMPOUNDV4_ARG_ADD_OP_READ(argnfs4, &(file_descriptor->stateid), offset, buffer_size);
00525 
00526   resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u.
00527       resok4.data.data_val = buffer;
00528 
00529   TakeTokenFSCall();
00530 
00531   /* Call the NFSv4 function */
00532   COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc);
00533   if(rc != RPC_SUCCESS)
00534     {
00535       ReleaseTokenFSCall();
00536 
00537       Return(ERR_FSAL_IO, rc, INDEX_FSAL_read);
00538     }
00539 
00540   ReleaseTokenFSCall();
00541 
00542   /* >> convert error code, and return on error << */
00543   if(resnfs4.status != NFS4_OK)
00544     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_read);
00545 
00546   /* >> dont forget setting output vars : read_amount, end_of_file << */
00547   *end_of_file =
00548       resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u.
00549       resok4.eof;
00550   *read_amount =
00551       resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u.
00552       resok4.data.data_len;
00553 
00554   /* update the offset within the fsal_fd_t */
00555   file_descriptor->current_offset +=
00556       resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_READ].nfs_resop4_u.opread.READ4res_u.
00557       resok4.data.data_len;
00558 
00559   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read);
00560 
00561 }                               /* FSAL_read */
00562 
00590 fsal_status_t PROXYFSAL_write(fsal_file_t * file_desc,       /* IN */
00591                               fsal_op_context_t * p_context, /* IN */
00592                               fsal_seek_t * seek_descriptor,    /* IN */
00593                               fsal_size_t buffer_size,  /* IN */
00594                               caddr_t buffer,   /* IN */
00595                               fsal_size_t * write_amount        /* OUT */
00596     )
00597 {
00598   int rc;
00599   COMPOUND4args argnfs4;
00600   COMPOUND4res resnfs4;
00601   nfs_fh4 nfs4fh;
00602   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00603 
00604   fsal_off_t offset;
00605 
00606   struct timeval timeout = TIMEOUTRPC;
00607 
00608 #define FSAL_WRITE_NB_OP_ALLOC 2
00609 
00610   nfs_argop4 argoparray[FSAL_WRITE_NB_OP_ALLOC];
00611   nfs_resop4 resoparray[FSAL_WRITE_NB_OP_ALLOC];
00612 
00613   /* sanity checks. */
00614   if(!file_descriptor || !buffer || !write_amount)
00615     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write);
00616 
00617   if(seek_descriptor == NULL)
00618     offset = file_descriptor->current_offset;
00619   else
00620     {
00621       switch (seek_descriptor->whence)
00622         {
00623         case FSAL_SEEK_SET:
00624           offset = seek_descriptor->offset;
00625           break;
00626 
00627         case FSAL_SEEK_CUR:
00628           offset = seek_descriptor->offset + file_descriptor->current_offset;
00629           break;
00630 
00631         default:
00632         case FSAL_SEEK_END:
00633           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_write);
00634           break;
00635         }
00636     }
00637 
00638   /* Setup results structures */
00639   argnfs4.argarray.argarray_val = argoparray;
00640   resnfs4.resarray.resarray_val = resoparray;
00641   argnfs4.minorversion = 0;
00642   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Write" ; */
00643   argnfs4.tag.utf8string_val = NULL;
00644   argnfs4.tag.utf8string_len = 0;
00645   argnfs4.argarray.argarray_len = 0;
00646 
00647   /* Get NFSv4 File handle */
00648   if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &(file_descriptor->fhandle)) == FALSE)
00649     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write);
00650 
00651 #define FSAL_READ_IDX_OP_PUTFH    0
00652 #define FSAL_READ_IDX_OP_WRITE    1
00653 
00654   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00655   COMPOUNDV4_ARG_ADD_OP_WRITE(argnfs4, &(file_descriptor->stateid), offset, buffer,
00656                               buffer_size);
00657 
00658   TakeTokenFSCall();
00659 
00660   /* Call the NFSv4 function */
00661   COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc);
00662   if(rc != RPC_SUCCESS)
00663     {
00664       ReleaseTokenFSCall();
00665 
00666       Return(ERR_FSAL_IO, rc, INDEX_FSAL_write);
00667     }
00668 
00669   ReleaseTokenFSCall();
00670 
00671   /* >> convert error code, and return on error << */
00672   if(resnfs4.status != NFS4_OK)
00673     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_write);
00674 
00675   /* Set write_amount */
00676   *write_amount =
00677       (fsal_size_t) resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_WRITE].nfs_resop4_u.
00678       opwrite.WRITE4res_u.resok4.count;
00679 
00680   /* update the offset within the fsal_fd_t */
00681   file_descriptor->current_offset +=
00682       resnfs4.resarray.resarray_val[FSAL_READ_IDX_OP_WRITE].nfs_resop4_u.opwrite.
00683       WRITE4res_u.resok4.count;
00684 
00685   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write);
00686 }                               /* FSAL_write */
00687 
00702 fsal_status_t PROXYFSAL_close(fsal_file_t * file_desc        /* IN */
00703     )
00704 {
00705 #define FSAL_CLOSE_NB_OP_ALLOC 2
00706   int rc;
00707   COMPOUND4args argnfs4;
00708   COMPOUND4res resnfs4;
00709   nfs_argop4 argoparray[FSAL_CLOSE_NB_OP_ALLOC];
00710   nfs_resop4 resoparray[FSAL_CLOSE_NB_OP_ALLOC];
00711   struct timeval timeout = TIMEOUTRPC;
00712   char All_Zero[] = "\0\0\0\0\0\0\0\0\0\0\0\0"; /* 12 times \0 */
00713   nfs_fh4 nfs4fh;
00714   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00715 
00716   /* Setup results structures */
00717   argnfs4.argarray.argarray_val = argoparray;
00718   resnfs4.resarray.resarray_val = resoparray;
00719   argnfs4.minorversion = 0;
00720   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */
00721   argnfs4.tag.utf8string_val = NULL;
00722   argnfs4.tag.utf8string_len = 0;
00723   argnfs4.argarray.argarray_len = 0;
00724 
00725   /* sanity checks. */
00726   if(!file_descriptor)
00727     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);
00728 
00729   /* Check if this was a "stateless" open, then nothing is to be done at close */
00730   if(!memcmp(file_descriptor->stateid.other, All_Zero, 12))
00731    {
00732     Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);
00733    }
00734 
00735   /* Get NFSv4 File handle */
00736   if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *)&(file_descriptor->fhandle)) == FALSE)
00737     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);
00738 
00739 #define FSAL_CLOSE_IDX_OP_PUTFH 0
00740 #define FSAL_CLOSE_IDX_OP_CLOSE 1
00741   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00742   COMPOUNDV4_ARG_ADD_OP_CLOSE(argnfs4, file_descriptor->stateid);
00743 
00744   TakeTokenFSCall();
00745 
00746   /* Call the NFSv4 function */
00747   COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc);
00748   if(rc != RPC_SUCCESS)
00749     {
00750       ReleaseTokenFSCall();
00751 
00752       Return(ERR_FSAL_IO, rc, INDEX_FSAL_close);
00753     }
00754 
00755   ReleaseTokenFSCall();
00756 
00757   /* >> convert error code, and return on error << */
00758   if(resnfs4.status != NFS4_OK)
00759     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_close);
00760 
00761   /* Update fd structure */
00762   file_descriptor->stateid.seqid +=  1;
00763 
00764   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);
00765 }                               /* FSAL_close */
00766 
00781 fsal_status_t PROXYFSAL_close_by_fileid(fsal_file_t * file_desc /* IN */ ,
00782                                         fsal_u64_t fileid)
00783 #ifndef _USE_PROXY
00784 {
00785   return ERR_FSAL_NOTSUPP;
00786 }
00787 #else
00788 {
00789   int rc;
00790   COMPOUND4args argnfs4;
00791   COMPOUND4res resnfs4;
00792   nfs_fh4 nfs4fh_hldir;
00793   component4 name;
00794   char nameval[MAXNAMLEN];
00795   char filename[MAXNAMLEN];
00796   fsal_status_t fsal_status;
00797   struct timeval timeout = TIMEOUTRPC;
00798   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00799 
00800 #define FSAL_CLOSE_BY_FILEID_NB_OP 4
00801 
00802   nfs_argop4 argoparray[FSAL_CLOSE_BY_FILEID_NB_OP];
00803   nfs_resop4 resoparray[FSAL_CLOSE_BY_FILEID_NB_OP];
00804 
00805   /* sanity checks. */
00806   if(!file_descriptor)
00807     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid);
00808 
00809   /* Setup results structures */
00810   argnfs4.argarray.argarray_val = argoparray;
00811   resnfs4.resarray.resarray_val = resoparray;
00812   argnfs4.minorversion = 0;
00813   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Write" ; */
00814   argnfs4.tag.utf8string_val = NULL;
00815   argnfs4.tag.utf8string_len = 0;
00816   argnfs4.argarray.argarray_len = 0;
00817 
00818   /* Get NFSv4 File handle */
00819 
00820   if(fsal_internal_proxy_extract_fh
00821      (&nfs4fh_hldir, (fsal_handle_t *) &(file_descriptor->pcontext->openfh_wd_handle)) == FALSE)
00822     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid);
00823 
00824   snprintf(filename, MAXNAMLEN, ".ganesha.open_by_fid.%llu", fileid);
00825   name.utf8string_val = nameval;
00826 
00827   if(str2utf8(filename, &name) == -1)
00828     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close_by_fileid);
00829 
00830 #define FSAL_CLOSE_BY_FILEID_IDX_OP_PUTFH    0
00831 #define FSAL_CLOSE_BY_FILEID_IDX_OP_REMOVE   1
00832 
00833   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_hldir);
00834   COMPOUNDV4_ARG_ADD_OP_REMOVE(argnfs4, name);
00835 
00836   TakeTokenFSCall();
00837 
00838   /* Call the NFSv4 function */
00839   COMPOUNDV4_EXECUTE(file_descriptor->pcontext, argnfs4, resnfs4, rc);
00840   if(rc != RPC_SUCCESS)
00841     {
00842       ReleaseTokenFSCall();
00843 
00844       Return(ERR_FSAL_IO, rc, INDEX_FSAL_close_by_fileid);
00845     }
00846 
00847   ReleaseTokenFSCall();
00848 
00849   fsal_status = FSAL_close((fsal_file_t *)file_descriptor);
00850 
00851   Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_close_by_fileid);
00852 }
00853 #endif
00854 
00893 fsal_status_t PROXYFSAL_open_by_fileid(fsal_handle_t * filehandle, /* IN */
00894                                        fsal_u64_t fileid,       /* IN */
00895                                        fsal_op_context_t *context,      /* IN */
00896                                        fsal_openflags_t openflags,      /* IN */
00897                                        fsal_file_t * file_desc,      /* OUT */
00898                                        fsal_attrib_list_t *
00899                                        file_attributes /* [ IN/OUT ] */ )
00900 #ifndef _USE_PROXY
00901 {
00902   return ERR_FSAL_NOTSUPP;
00903 }
00904 #else
00905 {
00906   int rc;
00907   COMPOUND4args argnfs4;
00908   COMPOUND4res resnfs4;
00909   nfs_fh4 nfs4fh;
00910   nfs_fh4 nfs4fh_hldir;
00911   bitmap4 bitmap;
00912   uint32_t bitmap_res[2];
00913   uint32_t bitmap_open[2];
00914   uint32_t bitmap_getattr_res[2];
00915   uint32_t share_access;
00916   component4 name;
00917   char nameval[MAXNAMLEN];
00918   char filename[MAXNAMLEN];
00919   fsal_status_t fsal_status;
00920   proxyfsal_file_t * file_descriptor = (proxyfsal_file_t *)file_desc;
00921   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00922 
00923 #define FSAL_OPEN_BY_FILEID_NB_OP_ALLOC 7
00924 #define FSAL_OPEN_VAL_BUFFER  1024
00925 
00926   fsal_proxy_internal_fattr_t fattr_internal;
00927   fsal_attrib_list_t attributes;
00928   nfs_argop4 argoparray[FSAL_OPEN_BY_FILEID_NB_OP_ALLOC];
00929   nfs_resop4 resoparray[FSAL_OPEN_BY_FILEID_NB_OP_ALLOC];
00930   char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
00931   struct timeval timeout = TIMEOUTRPC;
00932   char owner_val[FSAL_PROXY_OWNER_LEN];
00933   unsigned int owner_len = 0;
00934 
00935   /* sanity checks.
00936    * note : file_attributes is optional.
00937    */
00938   if(!filehandle || !p_context || !file_descriptor)
00939     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid);
00940 
00941   PRINT_HANDLE("FSAL_open_by_fileid", filehandle);
00942 
00943   if(((proxyfsal_handle_t *)filehandle)->data.object_type_reminder != FSAL_TYPE_FILE)
00944     {
00945       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_fileid);
00946     }
00947 
00948   /* Create the owner */
00949   snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu",
00950            getpid(), p_context, (unsigned long long int)((proxyfsal_op_context_t *)p_context)->file_counter);
00951   owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN);
00952   ((proxyfsal_op_context_t *)p_context)->file_counter += 1;
00953 
00954   /* Setup results structures */
00955   argnfs4.argarray.argarray_val = argoparray;
00956   resnfs4.resarray.resarray_val = resoparray;
00957   argnfs4.minorversion = 0;
00958   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Open By Name" ; */
00959   argnfs4.tag.utf8string_val = NULL;
00960   argnfs4.tag.utf8string_len = 0;
00961   argnfs4.argarray.argarray_len = 0;
00962 
00963   fsal_internal_proxy_setup_fattr(&fattr_internal);
00964 
00965   snprintf(filename, MAXNAMLEN, ".ganesha.open_by_fid.%llu", fileid);
00966   name.utf8string_val = nameval;
00967 
00968   if(str2utf8(filename, &name) == -1)
00969     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid);
00970 
00971   /* Get NFSv4 File handle */
00972   if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE)
00973     {
00974       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid);
00975     }
00976 
00977   if(fsal_internal_proxy_extract_fh(&nfs4fh_hldir, (fsal_handle_t *) &(p_context->openfh_wd_handle)) ==
00978      FALSE)
00979     {
00980       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid);
00981     }
00982   bitmap.bitmap4_val = bitmap_open;
00983   bitmap.bitmap4_len = 2;
00984   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00985 
00986   share_access = 0;
00987   if((openflags & FSAL_O_RDWR) == FSAL_O_RDWR)
00988     share_access |= OPEN4_SHARE_ACCESS_BOTH;
00989 
00990   if((openflags & FSAL_O_RDONLY) == FSAL_O_RDONLY)
00991     share_access |= OPEN4_SHARE_ACCESS_READ;
00992 
00993   if(((openflags & FSAL_O_WRONLY) == FSAL_O_WRONLY) ||
00994      ((openflags & FSAL_O_APPEND) == FSAL_O_APPEND))
00995     share_access |= OPEN4_SHARE_ACCESS_WRITE;
00996 
00997   /* >> you can check if this is a file if the information
00998    * is stored into the handle << */
00999 #define FSAL_OPEN_BYFID_IDX_OP_PUTFH         0
01000 #define FSAL_OPEN_BYFID_IDX_OP_SAVEFH        1
01001 #define FSAL_OPEN_BYFID_IDX_OP_PUTFH_HLDIR   2
01002 #define FSAL_OPEN_BYFID_IDX_OP_LINK          3
01003 #define FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE 4
01004 #define FSAL_OPEN_BYFID_IDX_OP_GETFH         5
01005 #define FSAL_OPEN_BYFID_IDX_OP_GETATTR       6
01006   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
01007   COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4);
01008   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_hldir);
01009   COMPOUNDV4_ARG_ADD_OP_LINK(argnfs4, name);
01010   COMPOUNDV4_ARG_ADD_OP_OPEN_NOCREATE(argnfs4, file_descriptor->stateid.seqid,
01011                                       p_context->clientid, share_access, name, owner_val,
01012                                       owner_len);
01013   COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
01014   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
01015 
01016   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
01017       OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res;
01018   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
01019       OPEN4res_u.resok4.attrset.bitmap4_len = 2;
01020 
01021   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
01022       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
01023   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
01024       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
01025 
01026   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
01027       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
01028       (char *)&fattr_internal;
01029   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
01030       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
01031       sizeof(fattr_internal);
01032 
01033   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
01034       GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
01035   resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
01036       GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
01037 
01038   TakeTokenFSCall();
01039 
01040   /* Call the NFSv4 function */
01041   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
01042   if(rc != RPC_SUCCESS)
01043     {
01044       ReleaseTokenFSCall();
01045 
01046       Return(ERR_FSAL_IO, rc, INDEX_FSAL_open_by_fileid);
01047     }
01048 
01049   ReleaseTokenFSCall();
01050 
01051   /* >> convert error code, and return on error << */
01052   if(resnfs4.status != NFS4_OK)
01053     {
01054       return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_open_by_fileid);
01055     }
01056 
01057   /* Use NFSv4 service function to build the FSAL_attr */
01058   if(nfs4_Fattr_To_FSAL_attr(&attributes,
01059                              &resnfs4.resarray.
01060                              resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETATTR].nfs_resop4_u.
01061                              opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
01062     {
01063       FSAL_CLEAR_MASK(file_attributes->asked_attributes);
01064       FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
01065 
01066       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open_by_fileid);
01067     }
01068 
01069   if(file_attributes)
01070     {
01071       memcpy(file_attributes, &attributes, sizeof(attributes));
01072     }
01073 
01074   /* Keep the returned stateid for later use */
01075   file_descriptor->stateid.seqid =
01076       resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.opopen.
01077       OPEN4res_u.resok4.stateid.seqid;
01078   memcpy((char *)file_descriptor->stateid.other,
01079          resnfs4.resarray.resarray_val[FSAL_OPEN_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.
01080          opopen.OPEN4res_u.resok4.stateid.other, 12);
01081 
01082   /* >> fill output struct << */
01083   /* Build the handle */
01084   if(fsal_internal_proxy_create_fh
01085      (&resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
01086       GETFH4res_u.resok4.object, FSAL_TYPE_FILE, attributes.fileid,
01087       (fsal_handle_t *) &file_descriptor->fhandle) == FALSE)
01088     {
01089       gsh_free(name.utf8string_val);
01090       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_fileid);
01091     }
01092 
01093   file_descriptor->openflags = openflags;
01094   file_descriptor->current_offset = 0;
01095   file_descriptor->pcontext = p_context;
01096 
01097   /* See if a OPEN_CONFIRM is required */
01098   if(resnfs4.resarray.resarray_val[FSAL_OPEN_BYFID_IDX_OP_OPEN_NOCREATE].nfs_resop4_u.
01099      opopen.OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM)
01100     {
01101       fsal_status = FSAL_proxy_open_confirm(file_descriptor);
01102       if(FSAL_IS_ERROR(fsal_status))
01103         Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_open);
01104     }
01105 
01106   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open_by_fileid);
01107 
01108 }                               /* FSAL_open_by_fileid */
01109 #endif
01110 
01111 unsigned int PROXYFSAL_GetFileno(fsal_file_t * pfile)
01112 {
01113   unsigned int intpfile;
01114 
01115   memcpy((char *)&intpfile, pfile, sizeof(unsigned int));
01116   return intpfile;
01117 }
01118 
01119 
01137 fsal_status_t PROXYFSAL_commit( fsal_file_t * p_file_descriptor,
01138                               fsal_off_t    offset, 
01139                               fsal_size_t   length )
01140 {
01141   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit);
01142 }