nfs-ganesha 1.4

fsal_symlinks.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 "nfs_proto_tools.h"
00037 #include "fsal_nfsv4_macros.h"
00038 
00067 fsal_status_t PROXYFSAL_readlink(fsal_handle_t * linkhandle,       /* IN */
00068                                  fsal_op_context_t *context,    /* IN */
00069                                  fsal_path_t * p_link_content,  /* OUT */
00070                                  fsal_attrib_list_t * link_attributes   /* [ IN/OUT ] */
00071     )
00072 {
00073 
00074   int rc;
00075 
00076   COMPOUND4args argnfs4;
00077   COMPOUND4res resnfs4;
00078   nfs_fh4 nfs4fh;
00079   bitmap4 bitmap;
00080   uint32_t bitmap_val[2];
00081   fsal_attrib_list_t attributes;
00082   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00083 
00084 #define FSAL_READLINK_NB_OP_ALLOC 4
00085   nfs_argop4 argoparray[FSAL_READLINK_NB_OP_ALLOC];
00086   nfs_resop4 resoparray[FSAL_READLINK_NB_OP_ALLOC];
00087   uint32_t bitmap_res[2];
00088 
00089   fsal_proxy_internal_fattr_t fattr_internal;
00090   char padpath[FSAL_MAX_PATH_LEN];
00091 
00092   struct timeval timeout = TIMEOUTRPC;
00093 
00094   /* sanity checks.
00095    * note : link_attributes is optional.
00096    */
00097   if(!linkhandle || !p_context || !p_link_content)
00098     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);
00099 
00100   /* Setup results structures */
00101   argnfs4.argarray.argarray_val = argoparray;
00102   resnfs4.resarray.resarray_val = resoparray;
00103   fsal_internal_proxy_setup_fattr(&fattr_internal);
00104   argnfs4.minorversion = 0;
00105   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readlink" ; */
00106   argnfs4.tag.utf8string_val = NULL;
00107   argnfs4.tag.utf8string_len = 0;
00108   argnfs4.argarray.argarray_len = 0;
00109 
00110   /* >> retrieve root handle filehandle here << */
00111   bitmap.bitmap4_val = bitmap_val;
00112   bitmap.bitmap4_len = 2;
00113   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00114 
00115   if(fsal_internal_proxy_extract_fh(&nfs4fh, linkhandle) == FALSE)
00116     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);
00117 
00118 #define FSAL_READLINK_IDX_OP_PUTFH     0
00119 #define FSAL_READLINK_IDX_OP_READLINK  1
00120 #define FSAL_READLINK_IDX_OP_GETATTR   2
00121 
00122   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00123   COMPOUNDV4_ARG_ADD_OP_READLINK(argnfs4);
00124   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00125 
00126   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00127       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
00128   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00129       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00130 
00131   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00132       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00133       (char *)&fattr_internal;
00134   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00135       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00136       sizeof(fattr_internal);
00137 
00138   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink.
00139       READLINK4res_u.resok4.link.utf8string_val = (char *)padpath;
00140   resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink.
00141       READLINK4res_u.resok4.link.utf8string_len = FSAL_MAX_PATH_LEN;
00142 
00143   TakeTokenFSCall();
00144 
00145   /* Call the NFSv4 function */
00146   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00147   if(rc != RPC_SUCCESS)
00148     {
00149       ReleaseTokenFSCall();
00150 
00151       Return(ERR_FSAL_IO, rc, INDEX_FSAL_readlink);
00152     }
00153 
00154   ReleaseTokenFSCall();
00155 
00156   /* >> convert error code and return on error << */
00157   if(resnfs4.status != NFS4_OK)
00158     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readlink);
00159 
00160   /* >> convert fs output to fsal_path_t
00161    * for example, if this is a char * (link_content_out) :
00162    */
00163 
00164   if(fsal_internal_proxy_fsal_utf8_2_path(p_link_content,
00165                                           &(resnfs4.resarray.resarray_val
00166                                             [FSAL_READLINK_IDX_OP_READLINK].
00167                                             nfs_resop4_u.opreadlink.READLINK4res_u.resok4.
00168                                             link)) == FALSE)
00169 
00170     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);
00171 
00172   /* retrieves object attributes, if asked */
00173   if(link_attributes)
00174     {
00175       /* Use NFSv4 service function to build the FSAL_attr */
00176       if(nfs4_Fattr_To_FSAL_attr(&attributes,
00177                                  &resnfs4.resarray.
00178                                  resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.
00179                                  opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
00180         {
00181           FSAL_CLEAR_MASK(link_attributes->asked_attributes);
00182           FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00183 
00184           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_readlink);
00185         }
00186 
00187       memcpy(link_attributes, &attributes, sizeof(attributes));
00188 
00189     }
00190 
00191   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);
00192 
00193 }
00194 
00229 fsal_status_t PROXYFSAL_symlink(fsal_handle_t * parent_directory_handle,   /* IN */
00230                                 fsal_name_t * p_linkname,       /* IN */
00231                                 fsal_path_t * p_linkcontent,    /* IN */
00232                                 fsal_op_context_t *context,     /* IN */
00233                                 fsal_accessmode_t accessmode,   /* IN (ignored) */
00234                                 fsal_handle_t * link_handle,       /* OUT */
00235                                 fsal_attrib_list_t * link_attributes    /* [ IN/OUT ] */
00236     )
00237 {
00238 
00239   int rc;
00240 
00241   COMPOUND4args argnfs4;
00242   COMPOUND4res resnfs4;
00243   nfs_fh4 nfs4fh;
00244   bitmap4 bitmap;
00245   uint32_t bitmap_res[2];
00246   uint32_t bitmap_mkdir[2];
00247   uint32_t bitmap_getattr_res[2];
00248   uint32_t bitmap_conv_val[2];
00249   fattr4 input_attr;
00250   bitmap4 convert_bitmap;
00251   component4 name;
00252   char nameval[MAXNAMLEN];
00253   component4 linkname;
00254   char linknameval[MAXNAMLEN];
00255   char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
00256 
00257   fsal_proxy_internal_fattr_t fattr_internal;
00258   fsal_attrib_list_t create_mode_attr;
00259   fsal_attrib_list_t attributes;
00260   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00261 
00262 #define FSAL_SYMLINK_NB_OP_ALLOC 4
00263 #define FSAL_SYMLINK_VAL_BUFFER  1024
00264 
00265   nfs_argop4 argoparray[FSAL_SYMLINK_NB_OP_ALLOC];
00266   nfs_resop4 resoparray[FSAL_SYMLINK_NB_OP_ALLOC];
00267 
00268   struct timeval timeout = TIMEOUTRPC;
00269 
00270   /* sanity checks.
00271    * note : link_attributes is optional.
00272    */
00273   if(!parent_directory_handle ||
00274      !p_context || !link_handle || !p_linkname || !p_linkcontent)
00275     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00276 
00277   /* Tests if symlinking is allowed by configuration. */
00278 
00279   if(!global_fs_info.symlink_support)
00280     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);
00281 
00282   /* Setup results structures */
00283   argnfs4.argarray.argarray_val = argoparray;
00284   resnfs4.resarray.resarray_val = resoparray;
00285   argnfs4.minorversion = 0;
00286   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Symlink" ; */
00287   argnfs4.tag.utf8string_val = NULL;
00288   argnfs4.tag.utf8string_len = 0;
00289   argnfs4.argarray.argarray_len = 0;
00290 
00291   fsal_internal_proxy_setup_fattr(&fattr_internal);
00292 
00293   convert_bitmap.bitmap4_val = bitmap_conv_val;
00294   convert_bitmap.bitmap4_len = 2;
00295 
00296   memset((char *)&name, 0, sizeof(component4));
00297   name.utf8string_val = nameval;
00298   name.utf8string_len = sizeof(nameval);
00299   if(fsal_internal_proxy_fsal_name_2_utf8(p_linkname, &name) == FALSE)
00300     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00301 
00302   memset((char *)&linkname, 0, sizeof(component4));
00303   linkname.utf8string_val = linknameval;
00304   if(fsal_internal_proxy_fsal_path_2_utf8(p_linkcontent, &linkname) == FALSE)
00305     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00306 
00307   /* Get NFSv4 File handle */
00308   if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
00309     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00310 
00311   bitmap.bitmap4_val = bitmap_mkdir;
00312   bitmap.bitmap4_len = 2;
00313   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00314 
00315   create_mode_attr.asked_attributes = FSAL_ATTR_MODE;
00316   create_mode_attr.mode = accessmode;
00317   fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap);
00318 
00319   if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
00320                             &create_mode_attr, &input_attr, NULL,       /* no compound data required here */
00321                             NULL,       /* No fh here, filehandle is not a settable attribute */
00322                             &convert_bitmap) == -1)
00323     Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_symlink);
00324 
00325 #define FSAL_SYMLINK_IDX_OP_PUTFH     0
00326 #define FSAL_SYMLINK_IDX_OP_SYMLINK   1
00327 #define FSAL_SYMLINK_IDX_OP_GETFH     2
00328 #define FSAL_SYMLINK_IDX_OP_GETATTR   3
00329   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00330   COMPOUNDV4_ARG_ADD_OP_SYMLINK(argnfs4, name, linkname, input_attr);
00331   COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
00332   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00333 
00334   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate.
00335       CREATE4res_u.resok4.attrset.bitmap4_val = bitmap_res;
00336   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate.
00337       CREATE4res_u.resok4.attrset.bitmap4_len = 2;
00338 
00339   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00340       GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
00341   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00342       GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
00343 
00344   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00345       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
00346   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00347       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00348 
00349   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00350       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00351       (char *)&fattr_internal;
00352   resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00353       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00354       sizeof(fattr_internal);
00355 
00356   TakeTokenFSCall();
00357 
00358   /* Call the NFSv4 function */
00359   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00360   nfs4_Fattr_Free(&input_attr);
00361   if(rc != RPC_SUCCESS)
00362     {
00363       ReleaseTokenFSCall();
00364 
00365       Return(ERR_FSAL_IO, 0, INDEX_FSAL_symlink);
00366     }
00367 
00368   ReleaseTokenFSCall();
00369 
00370   /* >> convert error code, and return on error << */
00371   if(resnfs4.status != NFS4_OK)
00372     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_symlink);
00373 
00374   /* Use NFSv4 service function to build the FSAL_attr */
00375   if(nfs4_Fattr_To_FSAL_attr(&attributes,
00376                              &resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].
00377                              nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
00378                              obj_attributes) != NFS4_OK)
00379     {
00380       FSAL_CLEAR_MASK(attributes.asked_attributes);
00381       FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);
00382 
00383       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_symlink);
00384     }
00385 
00386   if(link_attributes)
00387     {
00388       memcpy(link_attributes, &attributes, sizeof(attributes));
00389     }
00390 
00391   if(fsal_internal_proxy_create_fh
00392      (&
00393       (resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00394        GETFH4res_u.resok4.object), FSAL_TYPE_LNK, attributes.fileid,
00395       link_handle) == FALSE)
00396     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00397 
00398   /* OK */
00399   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
00400 }