nfs-ganesha 1.4

fsal_truncate.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #ifdef _SOLARIS
00019 #include "solaris_port.h"
00020 #endif                          /* _SOLARIS */
00021 
00022 #include <string.h>
00023 #ifdef _USE_GSSRPC
00024 #include <gssrpc/rpc.h>
00025 #include <gssrpc/xdr.h>
00026 #else
00027 #include <rpc/rpc.h>
00028 #include <rpc/xdr.h>
00029 #endif
00030 #include "nfs4.h"
00031 
00032 #include "fsal_internal.h"
00033 #include "fsal_convert.h"
00034 #include "fsal_common.h"
00035 
00036 #include "nfs_proto_functions.h"
00037 #include "nfs_proto_tools.h"
00038 #include "fsal_nfsv4_macros.h"
00039 
00067 fsal_status_t PROXYFSAL_truncate(fsal_handle_t * file_hdl,       /* IN */
00068                                  fsal_op_context_t * context,    /* IN */
00069                                  fsal_size_t length,    /* IN */
00070                                  fsal_file_t * file_descriptor, /* [IN|OUT] */
00071                                  fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */
00072     )
00073 {
00074 
00075   int rc;
00076 
00077   COMPOUND4args argnfs4;
00078   COMPOUND4res resnfs4;
00079   nfs_fh4 nfs4fh;
00080   uint64_t fileid;
00081   fsal_status_t fsal_status;
00082   fsal_attrib_list_t open_attrs;
00083   bitmap4 inbitmap;
00084   bitmap4 convert_bitmap;
00085   uint32_t inbitmap_val[2];
00086   uint32_t bitmap_res[2];
00087   uint32_t bitmap_set[2];
00088   uint32_t bitmap_conv_val[2];
00089   proxyfsal_handle_t * filehandle = (proxyfsal_handle_t *)file_hdl;
00090   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00091   struct fsal_handle_desc fhd = {
00092         .len = sizeof(fileid),
00093         .start = (caddr_t)&fileid
00094   };
00095 
00096 #define FSAL_TRUNCATE_NB_OP_ALLOC 3
00097   nfs_argop4 argoparray[FSAL_TRUNCATE_NB_OP_ALLOC];
00098   nfs_resop4 resoparray[FSAL_TRUNCATE_NB_OP_ALLOC];
00099 
00100   fsal_attrib_list_t fsal_attr_set;
00101   fattr4 fattr_set;
00102   fsal_proxy_internal_fattr_t fattr_internal;
00103   struct timeval timeout = TIMEOUTRPC;
00104 
00105   /* sanity checks.
00106    * note : object_attributes is optional.
00107    */
00108   if(!filehandle || !p_context)
00109     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);
00110 
00111   if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE)
00112     {
00113       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
00114     }
00115 
00116   if(file_descriptor)
00117     {
00118       /* First, we need to get the fileid on a filehandle base */
00119       fsal_status = FSAL_DigestHandle(context->export_context,
00120                                       FSAL_DIGEST_FILEID4, file_hdl, &fhd);
00121       if(FSAL_IS_ERROR(fsal_status))
00122         {
00123           Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
00124         }
00125 
00126       /* Then we have of open the file by fileid */
00127       open_attrs.asked_attributes = FSAL_ATTRS_POSIX;
00128       fsal_status = FSAL_open_by_fileid(file_hdl,
00129                                         fileid,
00130                                         context, FSAL_O_RDWR, file_descriptor, &open_attrs);
00131       if(FSAL_IS_ERROR(fsal_status))
00132         {
00133           Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
00134         }
00135     }
00136 
00137   /* Setup results structures */
00138   argnfs4.argarray.argarray_val = argoparray;
00139   resnfs4.resarray.resarray_val = resoparray;
00140   fsal_internal_proxy_setup_fattr(&fattr_internal);
00141   argnfs4.minorversion = 0;
00142   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */
00143   argnfs4.tag.utf8string_val = NULL;
00144   argnfs4.tag.utf8string_len = 0;
00145   argnfs4.argarray.argarray_len = 0;
00146 
00147   /* Get NFSv4 File handle */
00148   if(fsal_internal_proxy_extract_fh(&nfs4fh, file_hdl) == FALSE)
00149     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);
00150 
00151   /* Get prepared for truncate */
00152   fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE;
00153   fsal_attr_set.filesize = length;
00154 
00155   convert_bitmap.bitmap4_val = bitmap_conv_val;
00156   convert_bitmap.bitmap4_len = 2;
00157 
00158   fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap);
00159 
00160   if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
00161                             &fsal_attr_set, &fattr_set, NULL,   /* no compound data required here */
00162                             NULL,       /* No fh here, filehandle is not a settable attribute */
00163                             &convert_bitmap) == -1)
00164     Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate);
00165 
00166   inbitmap.bitmap4_val = inbitmap_val;
00167   inbitmap.bitmap4_len = 2;
00168   fsal_internal_proxy_create_fattr_bitmap(&inbitmap);
00169 
00170 #define FSAL_TRUNCATE_IDX_OP_PUTFH     0
00171 #define FSAL_TRUNCATE_IDX_OP_SETATTR   1
00172 #define FSAL_TRUNCATE_IDX_OP_GETATTR   2
00173   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00174   COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set);
00175   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap);
00176 
00177   /* For ATTR_SIZE, stateid is needed */
00178   if(file_descriptor)
00179     {
00180       argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr.
00181           stateid.seqid = ((proxyfsal_file_t *)file_descriptor)->stateid.seqid;
00182       memcpy(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.
00183           opsetattr.stateid.other, ((proxyfsal_file_t *)file_descriptor)->stateid.other, 12);
00184     }
00185   else
00186     {
00187       /* No file descriptor - use 'stateless' state_id of all-0s */
00188       argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr.
00189           stateid.seqid = 0;
00190       memset(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.
00191           opsetattr.stateid.other, 0, 12);
00192     }
00193 
00194   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00195       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
00196   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00197       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00198 
00199   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00200       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00201       (char *)&fattr_internal;
00202   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00203       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00204       sizeof(fattr_internal);
00205 
00206   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr.
00207       attrsset.bitmap4_val = bitmap_set;
00208   resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr.
00209       attrsset.bitmap4_len = 2;
00210 
00211   TakeTokenFSCall();
00212 
00213   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00214   nfs4_Fattr_Free(&fattr_set);
00215   if(rc != RPC_SUCCESS)
00216     {
00217       ReleaseTokenFSCall();
00218 
00219       Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate);
00220     }
00221 
00222   ReleaseTokenFSCall();
00223 
00224   if(resnfs4.status != NFS4_OK)
00225     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate);
00226 
00227   /* >> interpret error code << */
00228 
00229   /* >> Optionnaly retrieve post op attributes
00230    * If your filesystem truncate call can't return them,
00231    * you can proceed like this : <<
00232    */
00233   if(object_attributes)
00234     {
00235       if(nfs4_Fattr_To_FSAL_attr(object_attributes,
00236                                  &resnfs4.resarray.
00237                                  resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.
00238                                  opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
00239         {
00240           FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00241           FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00242 
00243           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
00244         }
00245 
00246     }
00247 
00248   if(file_descriptor)
00249     {
00250       /* Close the previously opened filedescriptor */
00251       fsal_status = FSAL_close_by_fileid(file_descriptor, fileid);
00252       if(FSAL_IS_ERROR(fsal_status))
00253         {
00254           Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
00255         }
00256     }
00257 
00258   /* No error occured */
00259   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate);
00260 }